如何排除与Perl正则表达式匹配的字符串部分?

时间:2010-10-13 10:10:24

标签: regex perl

我必须提交具有不同类型的行的文件。我想只选择那些拥有用户代理的行。我知道有这样的行是这样的。

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE; rv:1.8.1.16) Gecko/20080702 Firefox/2.0.0.16

所以,我想识别以字符串“User-Agent”开头的行,但之后我想处理除该字符串之外的其余行。我的问题是Perl将剩余的字符串存储在我可以用来进一步处理的任何特殊变量中吗?所以,基本上我想匹配以该字符串开头的行,但在该工作之后匹配其余部分,不包括该字符串。

我使用简单的正则表达式搜索该行

/^User-Agent:/

7 个答案:

答案 0 :(得分:3)

if ($line =~ /^User\-Agent\: (.*?)$/) {
    &process_string($1)
}

答案 1 :(得分:3)

(my $ remainder = $ str)= ~s / ^ User-Agent://;

答案 2 :(得分:3)

substr解决方案:

my $start = "User-Agent: ";

if ($start eq substr $line, 0, length($start)) {
    my $remainder = substr $line, length($start);
}

答案 3 :(得分:2)

您可以使用$'变量,但 - 这会增加很多开销。对于相同的目的,可能只是@+变量,或者English@LAST_MATCH_END

所以这会让你到达那里:

use English qw<@LAST_MATCH_END>;

my $value = substr( $line, $LAST_MATCH_END[0] );

答案 4 :(得分:2)

Perl 5.10有一个很好的功能,可以让您在没有性能问题的情况下获得$'解决方案的简单性。您使用/p标志和${^POSTMATCH}变量:

 use 5.010;
 if( $string =~ m/^User-Agent:\s+/ip ) {
      my $agent = ${^POSTMATCH};
      say $agent;
      }

但是还有其他一些技巧。如果您不能使用Perl 5.010或更高版本,则在标量上下文中使用全局匹配,pos的值是您在字符串中停止的位置。您可以在substr中使用该位置:

 if( $string =~ m/^User-Agent:\s+/ig ) {
      my $agent = substr $string, pos( $string );
      print $agent, "\n";
      }

pos@+ trick that Axeman shows类似。我想在第一章的掌握Perl 中我有一些@+@-的例子。

随着即将推出的Perl 5.14,还有另一种有趣的方法。 /r上的s///标记为a non-destructive substitution。也就是说,它匹配绑定的字符串,但在副本上执行替换并返回副本:

use 5.013;  # for now, but 5.014 when it's released
my $string = 'User-Agent: Firefox';
my $agent = $string =~ s/^User-Agent:\s+//r;
say $agent;

我认为/r起初很傻,但我真的开始喜欢它了。这么多事情变得非常简单。这类似于the idiom that M42 shows,但它有点棘手,因为旧的习语做了一个赋值,然后是一个替换,其中/r特征进行替换,然后进行赋值。你必须小心那里的括号,以确保正确的顺序发生。

请注意,在这种情况下,由于版本是Perl 5.12或更高版本,you automatically get strictures

答案 5 :(得分:0)

您可以使用$'捕获字符串的匹配后部分:

if ( $line =~ m/^User-Agent: / ) {
    warn $';
}

(注意冒号后面有一个尾随空格。)

但请注意,来自perlre

  

警告:一旦Perl看到您需要   $&amp;之一,$`或$'在任何地方   该计划,它必须提供它们   对于每个模式匹配。这可能   大大减慢您的计划。 Perl的   使用相同的机制生产$ 1,   2美元等,所以你也付出了代价   每个包含捕获的模式   括弧。 (为了避免这种成本   保留分组行为,使用   扩展的正则表达式(?:   ...)相反。)但如果你从不使用   $&安培; ,$`或$',然后没有模式   捕获括号不会   处罚。所以避免$&amp; ,$'和$`   如果你可以,但如果你不能(和一些   算法非常欣赏它们),   一旦你使用过它们,就使用它们   随意,因为你已经付了钱   价格。截至5.005,$&amp;不是这样   和其他两个一样昂贵。

答案 6 :(得分:0)

使用$'获取匹配右侧的字符串部分。

在其他答案中,关于“相当大的性能损失”,有许多嚎叫和咬牙切齿,但除非你真的知道你的程序使用正则表达式,并且你有性能问题,否则我不会担心它。

我们经常担心对实际代码几乎没有影响的优化。机会是,这也是其中之一。