负面的后方和方括号

时间:2013-07-01 13:07:41

标签: regex regex-negation negative-lookbehind

我想创建一个匹配无法匹配的右方括号的正则表达式。例子:

]ichael ==> match ]

[my name is Michael] ==> no match

我的文字中没有嵌套的方括号对。

我尝试使用负面的lookbehind,更具体地说,我使用这个正则表达式:(?<!\[(.)+)\]但它似乎没有做到这一点。

有什么建议吗?

4 个答案:

答案 0 :(得分:3)

除非您使用.NET,否则lookbehinds必须是固定长度的。既然你只是想检测是否有任何不匹配的右括号,你实际上并不需要一个lookbehind:

^[^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*\]

如果匹配,则您有一个不匹配的右括号。

如果您意识到[^\[\]]是一个与方括号匹配的否定字符类,并且如果您在freespacing模式中进行布局,那么理解起来会更容易理解:

^              # start from the beginning of the string
[^\[\]]*       # match non-bracket characters
(?:            # this group matches matched brackets and what follows them
  \[           # match [
  [^\[\]]*     # match non-bracket characters
  \]           # match ]
  [^\[\]]*     # match non-bracket characters
)*             # repeat 0 or more times
\]             # match ]

因此,在匹配0个或更多匹配良好的括号对后,尝试找到]

请注意,^]之间的部分在功能上等同于Tim Pietzker的解决方案(我认为这在概念上更容易理解)。我所做的是一种名为"unrolling the loop"的优化技术。如果您的风味提供了占有量词,您可以将所有*转换为*+以进一步提高效率。


关于您的尝试

即使你使用.NET,你的模式的问题是.允许你超越其他括号。因此,你在

中得不到匹配
[abc]def]

因为第一个和第二个]在他们面前的某处都有一个[。如果您使用的是.NET,最简单的解决方案是

(?<!\[[^\[\]]*)\]

这里我们在重复中使用非括号字符,这样我们就不会看到左边遇到的第一个[]

答案 1 :(得分:2)

你根本不需要环顾(并且很难使用它大多数语言不允许无限长度的lookbehind断言):

((?:\[[^\[\]]*]|[^\[\]]*)*+)\]

将匹配任何以结束括号结尾的文本,除非之前有相应的左括号。它没有(并根据您的问题不需要)处理嵌套括号。

可以在]中找到$1之前的部分,以便稍后重复使用。

<强>解释

(           # Match and capture in group number 1:
 (?:        # the following regex (start of non-capturing group):
  \[        # Either a [
  [^\[\]]*  # followed by non-brackets
  \]        # followed by ]
 |          # or
  [^\[\]]*  # Any number of non-bracket characters
 )*+        # repeat as needed, match possessively to avoid backtracking
)           # End of capturing group
\]          # Match ]

答案 2 :(得分:0)

这应该这样做:

'^[^\[]*\]'

基本上说要挑出任何在它与行首之间没有开放方括号的结束方括号。

答案 3 :(得分:-1)

\](.*)

将匹配]之后的所有内容:

]ichael -> ichael
[my name is Michael] ->