我的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模式中缺少什么?
答案 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)/'