我想使用Perl在两种模式中删除一些单词

以下是我的文字

..........

QWWK jhjh  kljdfh jklh jskdhf jkh PQXY
lhj ah jh sdlkjh PQXY jha slkdjh
PQXY jh alkjh ljk
kjhaksj dkjhsd KWWQ
hahs dkj h PQXY
.........


现在我想删除仅位于两个模式之间的所有PQXY
^QWWKKWWQ$

我知道如何通过以下命令替换两个模式之间的整个内容

perl -0777pe 's/^QWWK(?:(?!QWWK|KWWQ).)*KWWQ$/sometext/gms' filename


另请注意,^QWWK(?:(?!QWWK|KWWQ).)*KWWQ$此模式仅匹配之间没有QWWK和KWWQ的模式。

最佳答案

这是您尝试过的方法,需要更多的工作

perl -0777 -wpe's{^(QWWK (?:(?!QWWK|KWWQ).)*? KWWQ)$}{ $1 =~ s/PQXY//gr }egmsx' file


/e modifier使其以代码的形式评估替换面,然后在此处运行正则表达式。

在该正则表达式中,/r修饰符使其返回更改后的字符串(而不更改原始字符串,这使我们可以在只读的$1上运行它)。

上面的代码满足了^QWWK -to- KWWQ$文本块不包含这两个短语之一的要求,但是一些注释可能会有所帮助。

我们不需要非贪婪的.*?,因为.*(遵循负前瞻)实际上在KWWQ$处停止。但这很难确定,.*可能会把所有内容都吸收到最后一个KWWQ,包括所有其他可能的块以及它们之间的任何文本。

总之,我只是觉得.*?更安全,更简单,特别是因为这是必需的。

QWWK必须以一行开头(在问题中以^给出)作为块的标记。如果在块内找到额外的QWWK,则整个块不匹配。但是,如果里面的“额外” QWWK恰好在一行的开头,则


原来是块的不匹配,因为里面有QWWK
实际上是从QWWK开始匹配的块


我在上面使用/x以便能够将模式隔开以提高可读性。

09-20 18:22