我必须提交具有不同类型的行的文件。我想只选择那些拥有用户代理的行。我知道有这样的行是这样的。
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:/
答案 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)
使用$'
获取匹配右侧的字符串部分。
在其他答案中,关于“相当大的性能损失”,有许多嚎叫和咬牙切齿,但除非你真的知道你的程序使用正则表达式,并且你有性能问题,否则我不会担心它。
我们经常担心对实际代码几乎没有影响的优化。机会是,这也是其中之一。