如何合并两个正则表达式?兼顾括号与单引号内逗号不分割
正则表达式合并方案:同时忽略括号与单引号内的逗号分割
需求说明
需要实现按逗号分割字段时,同时忽略括号内和单引号内的逗号。现有两个正则各有缺陷:
- 正则1能忽略括号内的逗号,但会错误分割单引号内的内容
- 正则2能忽略单引号内的逗号,但会错误分割非开头括号内的内容
测试字符串:"10507, 'KEY,CUST', NAME(FIRST,LAST), (FIRST,LAST)"
现有正则的问题
正则1(忽略括号内逗号,但分割单引号内容)
正则表达式:/((?:[^(),]+ | ( \((?: [^()]+ | (?2) )*\) ))*)(?: ,\s* | $)/xg
匹配结果:
field 0: 10507 field 1: 'KEY field 2: CUST' field 3: NAME(FIRST,LAST) field 4: (FIRST,LAST)
缺陷:将'KEY,CUST'错误拆分为两个字段
正则2(忽略单引号内逗号,但分割非开头括号内容)
正则表达式:/(?:^|\s*,)\s*( '[^']*' | \([^)]*\) | [^,]*?(?=\s*(,|$)) )/xg
匹配结果:
field 0: 10507 field 1: 'KEY,CUST' field 2: NAME(FIRST field 3: LAST) field 4: (FIRST,LAST)
缺陷:将NAME(FIRST,LAST)错误拆分为两个字段
合并后的正则表达式
/(?:^|\s*,)\s*(?:'[^']*'|(?:[^(),]+|\((?:[^()]+|(?R))*\))+)(?=\s*(?:,|$))/xg
正则解析
(?:^|\s*,)\s*:定位字段起始位置,匹配字符串开头,或者逗号加任意空白字符,同时跳过字段前的空白(?:'[^']*':匹配单引号包裹的完整内容,单引号内的逗号不会触发分割|(?:[^(),]+|\((?:[^()]+|(?R))*\))+:匹配非引号、非括号的普通内容,或支持嵌套的括号结构:[^(),]+:匹配不包含逗号、括号的常规文本\((?:[^()]+|(?R))*\):匹配括号包裹的内容,(?R)递归调用整个正则,处理多层嵌套括号的情况
(?=\s*(?:,|$)):正向预查,确保当前匹配内容后是逗号(可带空白)或字符串结尾,作为字段结束标记
测试结果(符合期望)
field 0: 10507 field 1: 'KEY,CUST' field 2: NAME(FIRST,LAST) field 3: (FIRST,LAST)
内容的提问来源于stack exchange,提问作者James Finnegan
相关产品推荐
相关产品推荐

