问题描述
如何匹配下面字符串中()之间的2个不同的组
data foo (drop = DISCOUNT price RENAME = ( PROV_NM1= PROV_NM PROV_ST_NM1 = PROV_ST_NM) where = ( product = 'whizmo' and product < 10 )) bar( drop= DISCOUNT price rename= ( startDate = beginDate ) );
我需要匹配以获得2组:
-
foo (drop = DISCOUNT price RENAME = ( PROV_NM1= PROV_NM PROV_ST_NM1 = PROV_ST_NM) where = ( product = 'whizmo' and product < 10 ))
-
bar( drop= DISCOUNT price rename= ( startDate = beginDate ) )
几天来我一直在安静地尝试它,并提出了这个正则表达式:
(?i)(data)\s+((\w+)(?=(\s*))(?:\4\w+))?\s*(\(((.|\n)*?)\);)?
可以在这里看到:regex demo
它适用于大多数情况,但在上面的示例中,它没有给出2个单独的组,因为它与单个组中的方括号匹配。
我也尝试了一些递归模式,但遗憾的是无法弄清楚。任何帮助或指导上的赞赏。谢谢。
解决方法
在PCRE中,您可以使用此递归正则表达式捕获所需内容:
~(?: ^data | (?!^)\G ) \h+ ( \w+ \h* ( \( (?: [^()]*+ | (?-1) )* \) ) )~xi
您的比赛在已捕获的#1组
中进行RegEx详细信息:
-
(?: ^data | (?!^)\G )
:在一行中以data
开头,或者从上一个匹配项的末尾开始匹配,即\G
-
\h+
:匹配1个以上的空格 -
(
:启动捕获组#1-
\w+
:匹配1个以上的单词字符 -
\h*
:匹配0+个空格 -
(
:开始捕获组2-
\(
:匹配文字(
(正在打开) -
(?:
:启动非捕获组-
[^()]*+
:匹配0个或多个非(
和)
的字符 -
|
:或 -
(?-1)
:递归与最新组(即#2)进行的比赛
-
-
)*
:结束非捕获组。匹配该组中的0个或更多
-
-
)
:捕获#2
-
-
)
:捕获组#1
参考: RegEx Expression Recursion
,这最多可处理1级带括号的输入的嵌套:
\w+\s*\((?:\([^)]+\)|[^)])*?\)
请参见live demo。
它与一个单词匹配,后跟方括号输入,但包含一个替代 在尝试非闭合括号的更简单匹配之前,优先使用外部括号内的内部括号输入。
,我不是专家,但我会选择很多简单的方法
foo = ‘(foo.+?)bar’
bar = ‘(bar.+);’
#or combine both
‘(bar.+);|(foo.+?)bar’