perl 满足条件时排除单词

j2cgzkjk  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(181)

我有一个文本文件,我想排除“access”一词,因为a后面是a、b或c,位于第二、第三或第四个位置。

# cat tt.txt
access
ample
taxing

我试过了,但它返回了所有3个单词。

# grep '[a-c][^a-c][^a-c][^a-c]' tt.txt
access
ample
taxing

更新1:
我使用了上面过于简化的例子。

# cat tt.txt
access
bccess
ample
taxing
tacking
not

# grep -Ev '[a-c].{0,2}[a-c]' tt.txt
ample
taxing
not

# grep -E '[a-c].{0,2}[^a-c]' tt.txt
access
bccess
ample
taxing
tacking

# Expected
ample
taxing
fykwrbwg

fykwrbwg1#

我想排除单词access,因为a后面是abc,位于第二、第三或第四个位置
可以使用awk来完成:

awk '/[a-c]/ && !/[a-c].{0,2}[a-c]/' file

ample
taxing

RegEx细分:

  • [a-c]:匹配abc
  • .{0,2}:匹配0到2个任意字符
  • [a-c]:匹配abc

或者在gnu-grep中使用环视:

grep -P '^(?=.*[a-c])(?!.*[a-c].{0,2}[a-c])' file

ample
taxing

perl中的相同解决方案:

perl -ne 'print if /[a-c]/ && !/[a-c].{0,2}[a-c]/' file
s71maibg

s71maibg2#

据我所知你的情况是
1.字符串必须包含abc之一。
1.在位置0-3中,任何abc都不能位于另一abc之前。
那我们为什么不这样写代码呢

use strict;
use warnings;

while (<DATA>) {
    next unless /[a-c]/;                            # skip if no abc
    next if substr($_, 0, 4) =~ /(?<=[a-c])[a-c]/;  # skip if an abc is preceded by an abc 
    print;                                          # otherwise print
}

__DATA__
access
bccess
ample
taxing
tacking
not

这是一种编写代码来模拟菱形运算符<>的方法,由Perl oneliner中常用的-n-p开关使用。我们使用DATA文件句柄来模拟一个文件。如果你想将其转换为oneliner,它看起来像

$ perl -ne' next unless /[a-c]/; next if substr($_, 0, 4) =~ /(?<=[a-c])[a-c]/; print; ' file.txt

我已经在你的示例单词表上测试了它,它似乎和预期的一样工作。

相关问题