【问题标题】:Rexgex : How to catch anything between parenthesis except when its between square brackets正则表达式:如何在括号之间捕获任何内容,除非它在方括号之间
【发布时间】:2019-12-11 14:54:00
【问题描述】:

我需要一个正则表达式来捕获括号之间的任何内容,除非它位于以下模式之间,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

编辑:当您将括号直接放在方括号之后时,前面的正则表达式会失败,例如:

“我是一个(测试)S[但我是(没有被抓住)],抓住(我(如果可以的话))”

有没有人知道如何解决这个问题。谢谢。

【问题讨论】:

  • 请为您的示例指定预期结果。
  • 你不能只做两遍吗? replace(/S\[^]+\]/g,'') 然后捕获匹配的括号?
  • 如果您将其设为像 S\[.*?\]|(\(.*?\)) 这样的布尔值,那么您想要的结果将在 $1 中。如果您需要从输入中删除S,则可以像S?\[.*?\]|(\(.*?\)) 这样在正则表达式中将S 设为可选,或者将其从正则表达式中删除。
  • 试试 this: (?<=(?<!S)\[[^\]]*)\([^)]+\)(?=[^[]*\])|(?<=\([^)]*)\([^)]+\)(?=[^(]*\)) - 需要 ECMA2018+ 才能进行变量后视。
  • 试试(?<!S\[[^\]]+)\((?:[^()]|\([^)]*\))+\)

标签: javascript regex brackets


【解决方案1】:

您可以在 ECMA2018+(V8 引擎或更高版本)中使用以下正则表达式。以前的版本不支持可变长度的lookbehinds。

See regex in use here

(?<!S\[[^\]]+)\((?:[^()]|\([^)]*\))+\)

这是如何工作的:

  • (?&lt;!S\[[^\]]+) 否定后视确保以下内容不匹配:
    • S\[ 匹配 S[ 字面意思
    • [^\]]+ 匹配除] 之外的任何字符一次或多次
  • \( 匹配 ( 字面意思
  • (?:[^()]|\([^)]*\))+ 匹配以下任一选项一次或多次
    • [^()] 匹配除 () 之外的任何字符
    • \([^)]*\) 匹配(,然后匹配除) 之外的任何字符任意次数,然后匹配)
  • \) 匹配 ) 字面意思

但是请注意,这只匹配两个括号的深度(一组嵌套另一个)。您不能轻松在 JavaScript 的正则表达式引擎中平衡括号,因为当前不支持递归和其他标签。

This answer 解释了如何在不同的正则表达式引擎中平衡括号(包括 JavaScript,如果你使用 XRegExp)。

其他语言的一些实现示例 - 在 JavaScript 中不可能,因为它不包括递归、控制动词、平衡组等:

PCRESee here

S\[[^]]*\](*SKIP)(*FAIL)|\((?:[^()]|(?R))*\)

.NETSee here

(?<!S\[[^\]]+)\((?:[^()]|(?<p>\()|(?<-p>\)))+(?(p)(?!))\)

编辑

将后向 + 中的量词更改为 * 会阻止它匹配 S[(...)] 的大小写:

(?<!S\[[^\]]*)\((?:[^()]|\([^)]*\))+\)

【讨论】:

  • ++非常好的解决方案!
  • 这个用例失败:“我是一个(测试)S[(但我是(没有被抓住)],抓住(我(如果你可以的话))”
  • 有什么想法吗? @ctwheels 也许?
  • @xenope 根据您的问题,它不应该匹配 S[...] - 您是否正在寻找它与 S[...] 不匹配,除非它设置了嵌套括号 S[(())]?如果您尝试匹配 S[] 中的嵌套括号集,您是否还希望匹配 S[] 部分或仅匹配嵌套括号集部分:S[(a(b))] 或在该示例中仅匹配 (a(b))
  • @ctwheels 嗨,它永远不应该匹配 S[...] 里面的任何东西,在这种情况下,如果我们在括号后面加上括号,它匹配它但我不想.
猜你喜欢
  • 1970-01-01
  • 2018-04-04
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
相关资源
最近更新 更多