我的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 的负面查找结果如下...:
> 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 模式中缺少什么吗?
grep 在根据正则表达式检查的字符串中不包含换行符,因此当 abc 位于行尾时
abc\s
不匹配。在 perl 中 chomp 或使用 -l 命令行选项,您将看到类似的结果。
我不确定您为什么要在 perl 和 grep 正则表达式之间进行其他更改;
(?)
应该实现什么目标?
我会尝试像这样锚定你的正则表达式:
/(^abc\s+(?!def).+)/
这将捕获:
abc 123
abc de
否定前瞻正则表达式开头的
(?)
是多余的
在你的
perl -ne 'print if /(?)abc\s(?!def)/'
中,你要求perl找到abc
,然后是空格,然后字符串不应该是def
。这与def abc
匹配成功,因为这里def
后面没有abc
,而\s
与换行符匹配。
perl -ne 'print if /(?)abc\s(?!def)/'
首先,正如fugi所说,
(?)
是一个空的非捕获组,并且匹配任何东西,所以它什么也不做。
因此,正如所写,此正则表达式匹配文字字符串
abc
后跟单个 [:space:OR:tab:OR:newline]
,not 后跟文字字符串 def
。
因为
\s
匹配换行符,并且在处理每一行时没有截断尾随换行符,所以 def abc
匹配,因为正则表达式中的 (?)abc\s
匹配 abc[:newline:]
,后跟 $
(结尾 -线下锚,不是def
)。
更正后的正则表达式(考虑到冗余的
(?)
)将是:
perl -ne 'print if /(?<=abc)\s(?!def)/'
...匹配单个
[:space:OR:tab:OR:newline]
,其前面是 abc
和 not,后跟 def
。
这个 still 将匹配
def abc
,因为 \s
再次匹配 [:newline:]
,其前面是 abc
,后面是 $
(行尾锚点,而不是 def
) ).
在 Perl 中评估正则表达式之前,请删除
[:newline:]
,或者使用字符类 [ ] (如果需要考虑制表符)而不是 \s
:
perl -ne 'print if /(?<=abc)[ \t](?!def)/'
或者简单地
perl -ne 'print if /(?<=abc) (?!def)/'