如果我正确理解了您的问题,使用正则表达式以外的其他工具可能会更清楚。以下确实会将单词之间的任何空格折叠为一个空格。
输入 qwwk.txt(加一行)
..........
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
.........
KWWQ in mid line doesn't trigger: QWWK a PQXY b KWWQ c QWWK d PQXY e KWWQ
命令 perl qwwk.pl qwwk.txt
输出
..........
QWWK jhjh kljdfh jklh jskdhf jkh
lhj ah jh sdlkjh jha slkdjh
jh alkjh ljk
kjhaksj dkjhsd KWWQ
hahs dkj h PQXY
.........
KWWQ in mid line doesn't trigger: QWWK a PQXY b KWWQ c QWWK d PQXY e KWWQ
程序 qwwk.pl
use strict; use warnings;
while(<>) { # for each line
my @out;
my @words=split; # get its words
for my $i (0..$#words) {
my $w=$words[$i];
my $active = ($i==0 && $w eq q(QWWK)) .. ($i==$#words && $w eq q(KWWQ));
# Keep track of where we are. See notes below.
push @out, $w unless $active and ($w eq q(PQXY));
# Save words we want to keep
} #foreach word
print join(q( ), @out), qq(\n); # Print the words we saved
} #foreach line
关键是$active= FOO .. BAR 赋值中的触发器 (..) 运算符保持其状态,无论周围发生什么。这将是真实的
行首的QWWK (($i==0 && $w eq q(QWWK))) 到行尾的KWWQ (($i==$#words && $w eq q(KWWQ))),无论有多少行介入。
单线
perl -Mstrict -Mwarnings -ne 'my @out; my @words=split; for my $i (0..$#words) { my $w=$words[$i]; my $active = ($i==0 && $w eq q(QWWK)) .. ($i==$#words && $w eq q(KWWQ)); push @out, $w unless $active and ($w eq q(PQXY)); } print join(q( ), @out), qq(\n);' qwwk.txt
这里的区别在于-n 提供了while(<>){} 循环,因此-e 脚本中不包含该循环。 (另外,现在你知道我为什么在独立程序中使用q() 和qq() 了;)。)