如果一个字符跟随另一个字符,我不想要匹配,这是可选的

时间:2013-01-12 00:51:39

标签: regex perl string-matching

我希望匹配“错误”的任何变体(让我们假设在整个范围内不区分大小写),可能会或可能不会跟随一个字符,并且可能有也可能没有“s”。

例如,如果它具有以下内容,则返回匹配行:

text error: more text
text error more text
text errors more text
text errors( more text
text errors: more text
text errors:more text

但如果紧随其后有一个等号,我不希望它返回该行。例如:

text errors= more text

基本上,当“错误”或“错误”后面有“=”符号时,它总是“错误”。

我没有提出更多:

(?i)errors?[^\=]

不区分大小写,字符e,r,r,o,r,也许是s,而后面跟不是“=”就是我读的那个。

1 sample text, more text, errors=123456 more text more text
2 drops=0 link status good errors=0 adapter
3 Error: process failed to start
4 process [ERROR] failed
5 this line might have both ERROR and error=5555 and more text
6 there might be a line that has error=0x02343329 ERROR and more text

我想要返回第3,4,5和6行,而不是1或2。

没有成功。感谢您的帮助。

7 个答案:

答案 0 :(得分:1)

这么多答案,所有这些都很接近。你想要的是:/error(?!s=)/im

您不需要使用内联组,而是使用/ i标志。

我可能误解了你的问题,我不确定。但是,如果您也想禁用error=blah,只需改为使用/error(?!s?=)/im

演示+解释:http://regex101.com/r/oE1eQ9

答案 1 :(得分:1)

所以你想匹配“错误”,只要它没有跟着“=”或“s =”。这很简单:

/error(?!=|s=)/

你甚至可以把它写成

/error(?!s?=)/

如果你真的想在可能的情况下匹配“错误”(为了设置${^MATCH}或其他东西),你可以使用

/error(?![s=])|errors(?!=)/

您遇到问题,因为/ [^=] /匹配“s”。

答案 2 :(得分:0)

尝试使用先行断言:

(?i)errors?(?!\=)

答案 3 :(得分:0)

逻辑OR怎么样?

(?i)error[^s=]|errors[^=]

答案 4 :(得分:0)

尝试:

(?i)\berror(?!s?=)

单词锚点,然后是error,只要后面没有可选的s然后是等号。

(?!...)是一个负向前瞻,也是一个锚点(如^$),因为它不消耗文本(它是一个零宽度断言)

答案 5 :(得分:0)

亲爱的,亲爱的。很多人认为他们知道正则表达式!

在你自己的正则表达式(?i)errors?[^\=]中(正如有人说的那样,=不需要转义,但它没有任何害处)[^\=]并不意味着“没有遵循用等号“,表示”后跟一个不是等号的字符“。除非error位于字符串的末尾,否则两者是相同的,因此'error' =~ (?i)errors?[^\=]返回false。

“未跟随等号”需要否定前瞻,所以乍一看它看起来像你想要(?i)errors?(?!=),但如果正则表达式引擎找到errors=它会回溯并尝试匹配没有可选的s,看看它是否可以使整个模式与该方式匹配,然后会成功,因为errors error后面没有等号。

要解决此问题,您需要无回溯构造(?>...),一旦找到匹配项,就不允许回溯。正则表达式(?i)(?>errors?)(?!=)可以满足您的需求。

最后,为了允许在“errorerrors之后不久拒绝等号,你需要一些可选的空格,然后给出(?i)(?>errors?)(?!\s*=)

该程序演示

use strict;
use warnings;

while (<DATA>) {
  chomp;
  printf "%-70s %s\n", $_, /(?i)(?>errors?)(?!\s*=)/ ? 'YES' : 'NO';
}

__DATA__
text error: more text
text error more text
text errors more text
text errors( more text
text errors: more text
text errors:more text
text errors= more tex
text errors = more tex
text error= more tex
text error = more tex
1 sample text, more text, errors=123456 more text more text
2 drops=0 link status good errors=0 adapter
3 Error: process failed to start
4 process [ERROR] failed
5 this line might have both ERROR and error=5555 and more text
6 there might be a line that has error=0x02343329 ERROR and more text

<强>输出

text error: more text                                                  YES
text error more text                                                   YES
text errors more text                                                  YES
text errors( more text                                                 YES
text errors: more text                                                 YES
text errors:more text                                                  YES
text errors= more tex                                                  NO
text errors = more tex                                                 NO
text error= more tex                                                   NO
text error = more tex                                                  NO
1 sample text, more text, errors=123456 more text more text            NO
2 drops=0 link status good errors=0 adapter                            NO
3 Error: process failed to start                                       YES
4 process [ERROR] failed                                               YES
5 this line might have both ERROR and error=5555 and more text         YES
6 there might be a line that has error=0x02343329 ERROR and more text  YES

答案 6 :(得分:-1)

零宽度前瞻是一个很好的答案。尝试:

 (?i)(?!errors?=)error

其中“(?!errors?=)”表示“提前查看它是否匹配”错误?=“。

更新: 这是为了解释问题中原始正则表达式(?i)errors?[^\=]的问题: 复杂的是,“贪婪”(man perlre)的方式和时间并不像它可能的那样贪婪,引用:

  

默认情况下,量化的子模式是“贪婪的”,也就是说,它会匹配   尽可能多的时间(给定一个特定的起始位置)   仍允许其余模式匹配。

注意句子的第二部分。原始表达式(?i)errors?[^\=]将匹配“errors =”(或“errors”),因为“s?”允许匹配0次以允许“[^ =]”匹配“s”。 这就是为什么它匹配6个编号的行。

当这样的匹配(*,+,?和其他)被拒绝时,正则表达式引擎内发生的事情称为“回溯”,匹配备份并尝试不同的路径以查看是否与更好地匹配整个正则表达式是可能的。独立的子表达式(?>),lookarounds(?=)(?!)及其否定形式,可以阻止或限制回溯,因为可以使用交替,似乎每个人都有不同的偏好,因为我认为它们中的大多数出现在某处。到目前为止,没有人似乎使用“占有”来给你原来的正则表达式做了最小的无回溯变化?+形式:

errors?+[^\=]