匹配除“_iq_”之外的所有内容

时间:2012-08-15 16:29:40

标签: regex string perl

编辑:抱歉!我之前应该提到这一点。在您的回答中,请不要认为下面列出的项目是我正在搜索的目录中的唯一内容。这些是我想要匹配的东西,除了指定的两个。感谢。

这应该很简单,但我尝试的一切都没有做到。我需要以下项目来匹配:

bodipr2__ds_di_uat
bodipr2__ds_dw_uat
bodipr2__ds_iq_uat
bodipr2__ds_iq_uat_back
bodipr2__ds_itsys_uat
bodipr2__ds_ppp_uat
bodipr2__ds_psd_uat
bodipr2__ds_usage_uat
bodits2__ds_pef_tst
bodits2__ds_ppp_tst
bodits2__ds_pri_tst

除了我想省略包含_iq_的两个。所以我写了一个这样的表达式:

bodi.*?__ds[^_iq_]

但是这省略了所有这些。如果我试试这个:

bodi.*?__ds_[^iq]

省略_itsys_一个。我猜它匹配的所有内容都不包含'i'或'q'。我希望它在那个位置省略不包含'_iq_'的内容。

我很尴尬,我甚至不得不问这个,但如果有人能指出我正确的方向,我会非常感激。

7 个答案:

答案 0 :(得分:4)

试试这个:bod[a-z\d]+__ds_(?!iq_)\w+
我已经从http://regexr.com?31rho

进行了测试

答案 1 :(得分:3)

只是为了解释为什么你尝试[^iq]无效,这是因为[^iq]表示“匹配任何一个字符,除非字符为“i”或“q”。[^_iq_]表示相同,但​​它也匹配“_”。

所以,在你的情况下,

  • bodi.*?__ds[^_iq_]会匹配100%,因为每个单独的sring在“ds”之后包含“_”,它将匹配[^_iq_]

  • bodi.*?__ds_[^iq]只匹配“ds”后面包含字母“i”或“q”的行,这将是 - 正如您现在可以猜到的那样 - 两者 { {1}}和_iq_行。

匹配“不包含iq”的正确方法是在Godspeed或FailedDev的答案中显示的否定前瞻_itsys_

答案 2 :(得分:1)

如果 匹配并且处理其余部分,您可以跳过:

#!/usr/bin/env perl

use strict;
use warnings;

while (<DATA>) {
    next if /^bodipr2__ds_iq_/;  # Skip if bodipr2__ds_iq_ is matched

    # Process data
    print;
}

__DATA__
bodipr2__ds_di_uat
bodipr2__ds_dw_uat
bodipr2__ds_iq_uat
bodipr2__ds_iq_uat_back
bodipr2__ds_itsys_uat
bodipr2__ds_ppp_uat
bodipr2__ds_psd_uat
bodipr2__ds_usage_uat
bodits2__ds_pef_tst
bodits2__ds_ppp_tst
bodits2__ds_pri_tst

使用grep

#!/usr/bin/env perl

use strict;
use warnings;

my @strings = qw(
  bodipr2__ds_di_uat
  bodipr2__ds_dw_uat
  bodipr2__ds_iq_uat
  bodipr2__ds_iq_uat_back
  bodipr2__ds_itsys_uat
  bodipr2__ds_ppp_uat
  bodipr2__ds_psd_uat
  bodipr2__ds_usage_uat
  bodits2__ds_pef_tst
  bodits2__ds_ppp_tst
  bodits2__ds_pri_tst
);
@strings = grep /^bodipr2__ds_iq_/ ? 0 : 1, @strings;

答案 3 :(得分:0)

您可以使用not来反转:

if (not /^bodi.*_iq_.*/) {
  print;
}

或:

if ($line !~ /^bodi.*_iq_.*/) {
   print;
}

答案 4 :(得分:0)

这个怎么样:

    use strict;
    use warnings;



    for (<DATA>)
    {
        chomp;
        if (! m/bodi.*_iq_/)
        {
            print $_ . "\n";
        }
    }

__DATA__
bodipr2__ds_di_uat
bodipr2__ds_dw_uat
bodipr2__ds_iq_uat
bodipr2__ds_iq_uat_back
bodipr2__ds_itsys_uat
bodipr2__ds_ppp_uat
bodipr2__ds_psd_uat
bodipr2__ds_usage_uat
bodits2__ds_pef_tst
bodits2__ds_ppp_tst
bodits2__ds_pri_tst

答案 5 :(得分:0)

这段代码:

while ($subject =~ m/^(?:(?!_iq_).)*$/g) {
    print $&, "\n";
}

将打印除这两个字符串之外的所有内容。您可以通过在(?!_iq_)之后添加更多否定前瞻来扩展此功能。

示例测试:

enter image description here

答案 6 :(得分:0)

我看到了你的编辑,并且我不确定是否可能出现这种情况,这会排除你想要包含的内容,但我尝试了这个并且它对我有用。

#!/usr/bin/perl

use strict;
use warnings;

my @words = qw(bodipr2__ds_di_uat
bodipr2__ds_dw_uat
bodipr2__ds_iq_uat
bodipr2__ds_iq_uat_back
bodipr2__ds_itsys_uat
bodipr2__ds_ppp_uat
bodipr2__ds_psd_uat
bodipr2__ds_usage_uat
bodits2__ds_pef_tst
bodits2__ds_ppp_tst
bodits2__ds_pri_tst);

print "Original data\n\n";

foreach my $print (@words)
{
    print "$print\n";
}

print "\nNew data\n\n";

foreach my $word (@words)
{
    next if $word =~ /bodi[a-z]+\d__[a-z]+_iq_[a-z]+/;
    print "$word\n";
}