REGEX - 只接受边界值(如果前面没有某个字符)?

时间:2014-04-15 13:34:21

标签: regex perl

如何使正则表达式只考虑边界是否有效,如果它没有某个字符?

例如,如果边界是括号,我不希望它将任何前面带有感叹号的括号字符视为有效,我该怎么做?

示例:

(Comp!)uter)

应该忽略!),它应该捕获整个字符串

我试过

\(.+?[^\!]\)

\(.+?(?!\!)\)

然而它们都不起作用。

5 个答案:

答案 0 :(得分:1)

您可以使用具有否定字符类和替换的组:

(?s)\((?>[^!)]+|!.)*\)

请注意,如果您的字符串在!字符后面包含换行符,则应使用s修饰符。

答案 1 :(得分:1)

如果我做对了,你想要捕捉括号内的内容,如果前面有!,那么右括号会被“转义”吗?

您可以使用类似

的内容
\([^)!]+(?:!.[^)!]*)*\)

\(          # opening parenthesis
[^)!]+      # anything but a closing parenthesis or a !
(?:         # non capturing group
    !.     # a ! followed by anything
    [^)!]*  # anything but a closing parenthesis or a !
)*          # capturing group pattern zero or more times
\)          # closing parenthesis

背后的想法是:

  • 在第一个(之后,我们会将)![^)!]+
  • 的所有内容进行匹配
  • 停止时,或者有!,如果是,我们会将以下字符与!.匹配,我们会重复[^)!]+
  • 或者我们有一个未转义的)我们关闭了比赛

答案 2 :(得分:1)

\(.+?[^\!]\)适用于您提供的示例。

$ perl -E'say "(Comp!)uter)" =~ /\( .+? [^!] \)/xs ? $& : "no match"'
(Comp!)uter)

但这种方法与()不匹配。


\(.+?(?!\!)\)已接近尾声。您想要查看后面的),因此您需要使用(?<! ... )

$ perl -E'say "(Comp!)uter)" =~ /\( .+? (?<! ! )\)/xs ? $& : "no match"'
(Comp!)uter)

环顾四周有点贵,使用?非贪婪修饰符可以解决任何问题,但优化很容易造成问题。我使用以下内容,它也匹配()

/\( (?: !. | [^!)]+ )* \)/sx

但是你总是想要警惕不必要的回溯。如果缺少结尾),则表现非常糟糕,可以按如下方式修复:

/\( (?: !. | [^!)]++ )*+ \)/sx

答案 3 :(得分:0)

如果你想捕获它的Comp,然后是uter,然后是'计算机,你应该尝试这样的事情:

(Comp(?:uter)?)

?:使第二个括号无法捕获,因此不会弄乱您的捕获组引用。

如果您希望在Comp的情况下捕捉uter,那么您需要积极展望:

(Comp(?=uter))

?=将通过查看以下文本来执行零宽度断言。 (有关负面预测,请参阅?!;有关正面和负面观察,请参见?<=?<!

答案 4 :(得分:0)

如果你想使用感叹号来否定只有括号,这应该有效

(?<=\()([a-zA-Z](!\))?)+(?=\))