我想使用perl在两种模式中删除一些单词
以下是我的文字
PQXY
现在,我想删除仅位于两个模式之间的所有^QWWK
单词
KWWQ$
和perl -0777pe 's/^QWWK(?:(?!QWWK|KWWQ).)*KWWQ$/sometext/gms' filename
我知道如何通过以下命令替换两个模式之间的整个内容
^QWWK(?:(?!QWWK|KWWQ).)*KWWQ$
还请注意,LinearLayout
此模式仅与之间没有QWWK和KWWQ的那些模式匹配。
答案 0 :(得分:3)
您可以使用范围运算符:
perl -pe 's/PQXY//g if /^QWWK/ .. /KWWQ$/'
答案 1 :(得分:2)
这是您尝试过的方法,仅需一点点工作即可
parseInt('5aab4') //5
// I expect the output is NaN.
perl -0777 -wpe's{^(QWWK (?:(?!QWWK|KWWQ).)*? KWWQ)$}{ $1 =~ s/PQXY//gr }egmsx' file
modifier使其将替换面作为代码进行评估,然后在此处运行正则表达式。
在该正则表达式中,/e
修饰符使其返回更改后的字符串(而不更改原始字符串,这使我们可以在只读的/r
上运行它)。
上面的代码满足了$1
至^QWWK
文本块中不包含上述任何一个短语的要求,但是一些注释可能会有所帮助。
我们不需要使用非贪婪的KWWQ$
,因为.*?
(遵循负前瞻)实际上停在.*
。但这很难确定,KWWQ$
才有可能将 all 包含到最后一个.*
,包括所有其他可能的块以及它们之间的任何文本。
总而言之,我发现KWWQ
更安全,更简单,特别是因为 是必需的。
.*?
必须以一行(在问题中以QWWK
开头)作为块的标记。如果在该块内找到额外的^
,则整个块不匹配。但是,如果里面的“多余” QWWK
恰好在一行的开头,那么
本来应该是块的不匹配,因为里面有QWWK
实际上是从那个 QWWK
我在上面使用了QWWK
,以便能够隔开该模式以提高可读性。
答案 2 :(得分:1)
更新: 要仅在^ QWWK和KWWQ $之间不存在QWWK或KWWQ的情况下替换PQXY,请尝试以下操作:
perl -pe 'if (/^QWWK/ .. /KWWQ$/) {s/PQXY//g if ! /.+QWWK/ && !/KWWQ.+/}' filename
我敢肯定它可以被清理/打高尔夫球,但是我认为它将满足您的要求。
答案 3 :(得分:1)
如果我正确理解了您的问题,则使用正则表达式以外的其他工具可能会更清楚。以下内容确实将单词之间的所有空白折叠为一个空格。
输入 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
的{{1}}到行尾(($i==0 && $w eq q(QWWK))
的{{1}}的{1}}。
单线
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
了。)