【问题标题】:Regex positive look-ahead not preventing a match正则表达式积极前瞻不会阻止匹配
【发布时间】:2019-10-22 19:13:43
【问题描述】:

如果this regex:

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

匹配abc(abc),但不匹配(abcabc),为什么我不能在积极的前瞻like this 中使用它?

^(?=(?:(?:\([^\(\)]+\))|(?:(?<!\()[^\(\)]+(?!\)))))(?:\(?[a-z]+\)?)$

例如匹配abc)

【问题讨论】:

  • 您的第一个正则表达式可以简化为^(?:\([^()]+\)|[^()]+)$。当你在前瞻中使用它时,你没有在最后锚定它,你没有使用$。您需要的第二个正则表达式就是^(?:\([a-z]+\)|[a-z]+)$。在 .NET 中,您还可以使用 ^(\()?[a-z]+(?(1)\))$,请参阅 demo
  • 您要遵循哪些规则?我最好的猜测是,您希望 a-z 不带括号,带左括号或右括号,或同时带括号。
  • 哇,棘手的@WiktorStribiżew。谢谢,我快疯了。并感谢您的削减。
  • @MonkeyZeus 是的,把它归结为,我想让字符包含在括号中或不包含在括号中。我试图阻止打开但不关闭,反之亦然。我将使用这种环视方法来查看许多不同的字符集,可选地用括号括起来。
  • 那么() 有效吗? a(b)ca)b(c)((ab(c) 呢?

标签: .net regex regex-lookarounds lookbehind


【解决方案1】:

您的第一个正则表达式可以简化为^(?:\([^()]+\)|[^()]+)$。当你在前瞻中使用它时,你没有在最后锚定它,你没有使用$。所以,直接的“快速修复”看起来像

^(?=(?:\([^()]+\)|[^()]+)$)\(?[a-z]+\)?$

请参阅regex demo

第二个正则表达式也可以写成^(?:\([a-z]+\)|[a-z]+)$,有两种选择,可以匹配括号内的小写字母字符串,也可以不匹配。

在 .NET 中,您也可以使用

^(\()?[a-z]+(?(1)\))$

demo

详情

  • ^ - 字符串开头
  • (\()? - 一个可选的捕获组 #1 匹配 (
  • [a-z]+ - 1+ 个小写字母(\p{Ll}+ 匹配任何小写 Unicode 字母)
  • (?(1)\)) - 条件构造:如果第 1 组匹配(如果有左括号)匹配 )
  • $ - 字符串结束。

【讨论】:

  • Ugg,我遇到的问题是我实际使用的模式不在字符串/行的末尾。在我的简化示例中是这样,但实际上我有许多这样的组串在一起,所以(123) (45) (678) 匹配但(123 (45) (678) 不应该匹配。我找不到任何其他方法来获得前瞻以排除当前匹配之外的字符,即它允许123)
  • 如果您知道一种像我一样强制执行模式的方法,我将不胜感激。我整天都在做这个。
  • P.S.我知道您的回答非常适合我的问题的编写方式;问题是我的例子太简单了。如果按计划进行,我会写一个新问题,如果你愿意,你也可以回答。
  • @rory.ap 您只想匹配带有成对括号的字符串吗?试试^[^()]*(?&gt;(?&gt;(?&lt;open&gt;\()[^()]*)+(?&gt;(?&lt;-open&gt;\))[^()]*)+)+(?(open)(?!))$,见demo
  • 嗯,不管有没有,它们都是成对的。所以“(123)(456)”是的; “123 456”是的; “123(456)”是的; “9876(123)456”是的; "(123 456" no; "(123 (456)" no; "1212 444) 2 (42)" no。这只是一个例子。括号内可以有更多组值(或没有)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多