正则表达式:如何捕捉括号之间的任何内容,除非它在方括号之间
Rexgex : How to catch anything between parenthesis except when its between square brackets
我需要一个正则表达式来捕获括号之间的任何内容,除非它位于以下模式之间,一个 S
字符后跟方括号:
S[]
比如这句话:
I am a (test) S[ but i am (not catched)], catch (me (if you can))
^^^^^^ ^^^^^^^^^^^^^^^^^ # should be matched
^^^^^^^^^^^^^^^^^^^^^^^^^^ # should not be matched
它还应该捕获嵌套的括号。
我尝试使用各种示例使其工作,但我得到的最接近的是这个:
(?![^S\[]*\])\(([^()]*|\(([^()]*|\(([^()]*|\([^()]*\))*\))*\))*\)?
=> 但当您从测试句子中删除 S
时它会失败。
知道怎么做吗?
编辑:应该像这种情况一样匹配,但考虑到 S:https://regex101.com/r/WzECSS/1
编辑:这个应该可以解决问题:(?<!S\[[^\]]+)\((?:[^()]|\([^)]*\))+\)
谢谢@ctwheels
编辑:当您将括号直接放在方括号之后时,前面的正则表达式会失败,例如:
"I am a (test) S[( but i am (not catched)], catch (me (if you can))"
有没有人知道如何解决这个问题。谢谢。
您可以在 ECMA2018+(V8 引擎或更高版本)中使用以下正则表达式。以前的版本不支持可变长度回顾。
(?<!S\[[^\]]+)\((?:[^()]|\([^)]*\))+\)
这是如何工作的:
(?<!S\[[^\]]+)
否定后视确保以下内容不匹配:
S\[
按字面意思匹配 S[
[^\]]+
匹配除 ]
之外的任何字符一次或多次
\(
按字面意思匹配 (
(?:[^()]|\([^)]*\))+
匹配以下任一选项一次或多次
[^()]
匹配除 (
和 )
之外的任何字符
\([^)]*\)
匹配 (
,然后匹配 )
以外的任何字符任意次数,然后 )
\)
按字面意思匹配 )
但是请注意,这仅匹配两个括号的深度(一组与另一组嵌套)。由于当前不支持递归和其他标记,因此您无法 轻松地 平衡 JavaScript 的正则表达式引擎中的括号。
This answer 解释了如何在不同的正则表达式引擎中平衡括号(如果您使用 XRegExp,则包括 JavaScript)。
其他语言的一些实现示例 - 在 JavaScript 中不可能,因为它不包括递归、控制动词、平衡组等:
PCRE: See here
S\[[^]]*\](*SKIP)(*FAIL)|\((?:[^()]|(?R))*\)
.NET: See here
(?<!S\[[^\]]+)\((?:[^()]|(?<p>\()|(?<-p>\)))+(?(p)(?!))\)
编辑
将 lookbehind 中的量词 +
更改为 *
可防止它匹配 S[(...)]
:
的大小写
(?<!S\[[^\]]*)\((?:[^()]|\([^)]*\))+\)
我需要一个正则表达式来捕获括号之间的任何内容,除非它位于以下模式之间,一个 S
字符后跟方括号:
S[]
比如这句话:
I am a (test) S[ but i am (not catched)], catch (me (if you can))
^^^^^^ ^^^^^^^^^^^^^^^^^ # should be matched
^^^^^^^^^^^^^^^^^^^^^^^^^^ # should not be matched
它还应该捕获嵌套的括号。
我尝试使用各种示例使其工作,但我得到的最接近的是这个:
(?![^S\[]*\])\(([^()]*|\(([^()]*|\(([^()]*|\([^()]*\))*\))*\))*\)?
=> 但当您从测试句子中删除 S
时它会失败。
知道怎么做吗?
编辑:应该像这种情况一样匹配,但考虑到 S:https://regex101.com/r/WzECSS/1
编辑:这个应该可以解决问题:(?<!S\[[^\]]+)\((?:[^()]|\([^)]*\))+\)
谢谢@ctwheels
编辑:当您将括号直接放在方括号之后时,前面的正则表达式会失败,例如:
"I am a (test) S[( but i am (not catched)], catch (me (if you can))"
有没有人知道如何解决这个问题。谢谢。
您可以在 ECMA2018+(V8 引擎或更高版本)中使用以下正则表达式。以前的版本不支持可变长度回顾。
(?<!S\[[^\]]+)\((?:[^()]|\([^)]*\))+\)
这是如何工作的:
(?<!S\[[^\]]+)
否定后视确保以下内容不匹配:S\[
按字面意思匹配S[
[^\]]+
匹配除]
之外的任何字符一次或多次
\(
按字面意思匹配(
(?:[^()]|\([^)]*\))+
匹配以下任一选项一次或多次[^()]
匹配除(
和)
之外的任何字符
\([^)]*\)
匹配(
,然后匹配)
以外的任何字符任意次数,然后)
\)
按字面意思匹配)
但是请注意,这仅匹配两个括号的深度(一组与另一组嵌套)。由于当前不支持递归和其他标记,因此您无法 轻松地 平衡 JavaScript 的正则表达式引擎中的括号。
This answer 解释了如何在不同的正则表达式引擎中平衡括号(如果您使用 XRegExp,则包括 JavaScript)。
其他语言的一些实现示例 - 在 JavaScript 中不可能,因为它不包括递归、控制动词、平衡组等:
PCRE: See here
S\[[^]]*\](*SKIP)(*FAIL)|\((?:[^()]|(?R))*\)
.NET: See here
(?<!S\[[^\]]+)\((?:[^()]|(?<p>\()|(?<-p>\)))+(?(p)(?!))\)
编辑
将 lookbehind 中的量词 +
更改为 *
可防止它匹配 S[(...)]
:
(?<!S\[[^\]]*)\((?:[^()]|\([^)]*\))+\)