如果一个字符跟随另一个字符(可选),我不想匹配
我想匹配“错误”的任何变体(让我们假设整个棋盘上不区分大小写),其中可能有也可能不跟随字符,并且可能有或没有“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
基本上,在“error”或“errors”后面有一个“=”符号时,它总是“错误”。
我无法想出比这更:
(?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。
不具有成功。我在这里先向您的帮助表示感谢。
零宽度预测是一个很好的答案。尝试:?
(?i)(?!errors?=)error
其中“(?!errors?=)
”是指“不期而遇提前检查不匹配‘错误=’
更新: 这是通过在原有的正则表达式(?i)errors?[^\=]
解释的问题问题: 的并发症是如何以及何时“贪婪”(人perlre)不是因为贪婪,因为它可能是,引用:
By default, a quantified subpattern is "greedy", that is, it will match as many times as possible (given a particular starting location) while still allowing the rest of the pattern to match.
注意句子的第二部分的原始表达式(?i)errors?[^\=]
将匹配“errors =”(或“errors”),因为“s?”允许匹配0次以允许“[^ =]”匹配“s”。 这就是为什么它匹配6个编号的行。
当这样的匹配(*,+,?等)被拒绝时,正则表达式引擎内发生的事情称为“回溯”,匹配备份并尝试不同的路径,以查看是否更好地匹配整个整体正则表达式是可能的。独立的子表达式(?>),lookarounds(?=)(?!)及其消极形式可以防止或限制回溯,就像使用交替一样,似乎每个人都有不同的偏好,因为我认为他们大多数都出现在某处。尽管目前为止没有人使用“所有格”为您的原始正则表达式提供最小的无回溯变化?+形式:
errors?+[^\=]
这一个似乎工作没有失败。我看到了很多我想看到的东西。谢谢。 – harperville
我不确定这是否会允许包含错误和错误=的行,然后将其返回。我对错误很感兴趣,只要它没有跟随=,但如果错误和错误=在同一行,我仍然希望它返回。 – harperville
@haperville,您是否在http://regex101.com/r/xV2aG6上尝试了答案? – dzieciou
怎么样的逻辑OR?
(?i)error[^s=]|errors[^=]
尝试:
(?i)\berror(?!s?=)
字锚,随后error
,只要它不跟一个可选的s
然后等号。
(?!...)
是负先行,也是在这个意义上的锚定(如^
和$
),它不消耗文本(它是一个零宽度断言)。
这么多的答案,如此接近他们所有人。你想要的是:/error(?!s=)/im
你不需要使用内联组,而是使用/ i标志。
我可能错过了你的问题,我不确定。但是,如果您也想禁止error=blah
,则只需使用/error(?!s?=)/im
。
+1用于在线演示结果。 – dzieciou
哦,亲爱的。很多人认为他们知道正则表达式!
在自己的正则表达式(?i)errors?[^\=]
(其中,正如有人所说,=
不需要逃避,但它并没有坏处)[^\=]
并不颇有意味“后面没有一个等号”,它意味着“之后一个不是等号的字符“。除非error
位于字符串末尾,否则两者相同,因此'error' =~ (?i)errors?[^\=]
返回false。
“后面没有一个等号”需要负先行,所以乍一看它看起来像你想(?i)errors?(?!=)
,但如果正则表达式引擎找到errors=
它会走回头路,尽量不选购s
匹配,看是否它可以得到整个模式匹配的方式,然后将成功,因为errors
是error
后面没有等号。
要解决此问题,您需要无回溯构造(?>...)
,一旦找到匹配项就不允许回溯。正则表达式(?i)(?>errors?)(?!=)
做你所需要的。
最后,为了允许拒绝等于“error
或errors
之后不久”,在它之前需要一些可选的空白区域,给出(?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
所以,你想匹配 “错误”,只要它不跟 “=” 或 “S =”。这是很简单的:
/error(?!=|s=)/
你甚至可以把它写成
/error(?!s?=)/
如果你真的想如果可能的话(为了设置${^MATCH}
什么的),则可以使用
/error(?![s=])|errors(?!=)/
您遇到问题,因为/ [^=]
/匹配项“s
”。
'errors?'使整个字符串'errors'可选。这可能是为什么3-6没有返回。你会想'错误(s?)'而不是。 – dzieciou
也等号需要转义,所以你应该有'='而不是'\ ='。 – dzieciou
@dzieciou“错误?使整个字符串错误可选。” fge