使用 grep 和 perl 进行正/负前瞻

问题描述 投票:0回答:4

我的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 模式中缺少什么吗?

regex bash perl grep regex-lookarounds
4个回答
9
投票

grep 在根据正则表达式检查的字符串中不包含换行符,因此当 abc 位于行尾时

abc\s
不匹配。在 perl 中 chomp 或使用 -l 命令行选项,您将看到类似的结果。

我不确定您为什么要在 perl 和 grep 正则表达式之间进行其他更改;

(?)
应该实现什么目标?


4
投票

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

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

这将捕获:

abc 123
abc de

否定前瞻正则表达式开头的

(?)
是多余的


2
投票

在你的

perl -ne 'print if /(?)abc\s(?!def)/'
中,你要求perl找到
abc
,然后是空格,然后字符串不应该是
def
。这与
def abc
匹配成功,因为这里
def
后面没有
abc
,而
\s
与换行符匹配。


0
投票
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)/'
© www.soinside.com 2019 - 2024. All rights reserved.