[英]Recursive regex for matching everything in parenthesis (PCRE)
我很惊讶,不容易找到一个类似的问题与答案的SO。 我想在某些功能中匹配所有内容。 想法是删除无用的功能。
foo(some (content)) --> some (content)
所以我试图匹配函数调用中的所有内容,包括括号。 这是我的PCRE正则表达式:
(?<name>\w+)\s*\(\K
(?<e>
[^()]+
|
[^()]*
\((?&e)\)
[^()]*
)*
(?=\))
https://regex101.com/r/gfMAIM/1
不幸的是它不起作用,我不明白为什么。
您的组e
模式没有正确的工作,目前,它匹配1个深度级别的括号,因为您只复制了一次e
模式。 它需要匹配尽可能多的(...)
子串,因此,子程序模式需要在*
或+
量化组内,甚至可以“简化”为(?<e>[^()]*(?:\\((?&e)\\)[^()]*)*)
。
请注意,您的组e
模式等于(?<e>[^()]+|\\((?&e)\\))*
。 [^()]*
围绕\\((?&e)\\)
是多余的,因为[^()]+
替代将消耗当前深度级别上的(
和)
之外的字符。
此外,您量化了组e
模式,使其成为重复捕获组 ,仅在最后一次迭代期间保持文本匹配。
你可以用
(?<name>\w+)\s*\(\K(?<e>[^()]*(?:\((?&e)\)[^()]*)*)(?=\))
请参阅正则表达式演示
细节
(?<name>\\w+)\\s*\\(\\K
- 1+个字符,0 +空格和(
从匹配中省略) (?<e>
- 小组e
开始
[^()]*
- 除了(
和)
以外的0+个字符 (?:
- 非捕获组的开始:
\\(
- a (
char (?&e)
- 递归组e
模式 \\)
- a )
[^()]*
- 除了(
和)
以外的0+个字符 )*
- 重复0次或更多次 )
- e
组结束 (?=\\))
- a )
必须立即在当前位置的右侧。 以下正则表达式进行匹配而不采取额外步骤:
(?<name>\w+)\s*(\((?<e>([^()]*+|(?2))+)\))
但是,这与在带引号的字符串中包含不平衡括号的后续字符串不匹配:
foo(bar = ')')
foo(bar(john = "(Doe..."))
所以你应该寻找的是:
(?<name>\w+)\s*(\((?<e>([^()'"]*+|"(?>[^"\\]*+|\\.)*"|'(?>[^'\\]*+|\\.)*'|(?2))+)\))
正则表达式细分:
(?<name>\\w+)\\s*
匹配函数名称和尾随空格 (
群集的开始
\\(
匹配文字(
(?<e>
命名捕获组e
(
开始捕获组#2
[^()'"]*+
匹配除()'"
之外的任何东西 |
要么 "(?>[^"\\\\]*+|\\\\.)*"
匹配双引号之间的任何内容 |
要么 '(?>[^'\\\\]*+|\\\\.)*'
匹配单引号之间的任何内容 |
要么 (?2)
递归第二个捕获组 )+
尽可能重复,至少一次 )
捕获组结束 \\)
匹配)
字面意思 )
捕获组结束 我有简单的正则表达式没有递归 。
(?<=[\w ]{2}\().*(?=\))
到目前为止它处理的是不平衡的perenthesis,但它不处理一行中的多个函数。 如果你知道函数之间的delmiters,它可能会被handeled。 例如;
如果那是Java代码。
变体2 (针对一行中的多个函数进行了更新):
(?<=[\w ]\()[^;\n]*(?=\))
变体3 (允许;
在字符串中):
(?<=[\w ]\()([^;\n]|".*?")*(?=\))
变体4 (逃避字符串):
(?<=[\w \n]\()(?:[^;\n"]|(?:"(?:[^"]|\\")*?(?<!\\)"))*(?=\))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.