grep和perl的正/负前瞻

时间:2013-12-18 11:28:40

标签: regex bash perl grep negative-lookahead

我的login.txt文件包含以下条目

abc def
abc 123
def abc
abc de
tha ewe

当我使用perl进行正向前瞻时,我得到以下结果

cat login.txt | perl -ne 'print if /(?)abc\s(?=def)/'
abc def

当我使用grep时,我得到以下结果

cat login.txt | grep -P '(?<=abc)\s(?=def)'
abc def

从perl和grep中得到的负面外观结果如下:

 cat login | perl -ne 'print if /(?)abc\s(?!def)/'
abc 123
def abc
abc de

grep结果

cat login.txt | grep -P '(?<=abc)\s(?!def)'
abc 123
abc de

perl与def abc匹配负向前瞻。但它不应该与def abc匹配,因为我正在检查abc然后def模式。 grep返回正确的结果。

在我的perl模式中缺少什么?

4 个答案:

答案 0 :(得分:6)

grep不包括它对正则表达式检查的字符串中的换行符,因此当abc位于行尾时,abc\s不匹配。在perl中使用chomp或使用-l命令行选项,您将看到类似的结果。

我不确定你为什么要在perl和grep regex之间进行其他更改; (?)应该完成什么?

答案 1 :(得分:3)

我会尝试像你这样锚定你的正则表达式:

/(^abc\s+(?!def).+)/

这将捕获:

abc 123
abc de

负向前瞻性正则表达式开头的(?)是多余的

答案 2 :(得分:2)

perl -ne 'print if /(?)abc\s(?!def)/'要求perl查找abc,然后是空格,则字符串不应为def。这与def abc成功匹配,因为此处def之后没有abc\s与换行匹配。

答案 3 :(得分:0)

perl -ne 'print if /(?)abc\s(?!def)/'

首先,如fugi所述,(?)是一个空的非捕获组,并且匹配任何内容,因此它什么也不做。

因此,按照正则表达式,此正则表达式与文字字符串abc和后跟单个[:space:OR:tab:OR:newline]匹配, not 后跟文字字符串def

因为\s匹配换行符,并且在处理每一行时都没有切尾的换行符,所以def abc匹配,因为正则表达式中的(?)abc\s匹配了abc[:newline:]后跟$(行尾锚点, not def)。

更正后的正则表达式(考虑冗余(?))将是:

perl -ne 'print if /(?<=abc)\s(?!def)/'

...与单个[:space:OR:tab:OR:newline]匹配,前跟abc,而 not 后跟def

still 将匹配def abc,因为\s再次匹配[:newline:],其后跟abc,然后跟{ {1}}(行尾锚,而不是$)。

在Perl中评估正则表达式前先将def切掉,或者使用字符类[\ t](如果需要考虑制表符),而不要使用[:newline:]

\s

或者简单地

perl -ne 'print if /(?<=abc)[ \t](?!def)/'
相关问题