![](/img/trans.png)
[英]How can I convert a string into a regular expression that matches itself in Perl?
[英]How can I exclude the part of the string that matches a Perl regular expression?
我必须归档具有不同类型的线。 我只想选择那些具有用户代理的行。 我知道具有这种功能的生产线就是这样。
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:/
if ($line =~ /^User\-Agent\: (.*?)$/) {
&process_string($1)
}
(我的$ remainder = $ str)=〜s / ^ User-Agent://;
substr解决方案:
my $start = "User-Agent: ";
if ($start eq substr $line, 0, length($start)) {
my $remainder = substr $line, length($start);
}
您可以使用$'
变量,但不要使用 -这会增加很多开销。 出于相同的目的,可能@LAST_MATCH_END
是@+
变量,或者用英语来说是@LAST_MATCH_END
。
因此,这将使您到达那里:
use English qw<@LAST_MATCH_END>;
my $value = substr( $line, $LAST_MATCH_END[0] );
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与Axeman显示的@+
技巧相似。 我想在第一章的Mastering Perl中有@+
和@-
一些示例。
对于即将推出的Perl 5.14,还有另一种有趣的方法可以做到这一点。 s///
上的/r
标志进行无损替换 。 也就是说,它匹配绑定的字符串,但是对副本执行替换并返回副本:
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
起初很傻,但是我真的开始喜欢它。 事实证明,这么多事情真的很容易。 这类似于M42所示的惯用法 ,但是有点棘手,因为旧惯用法先执行赋值然后进行替换,其中/r
功能执行替换后进行赋值。 您必须小心括号,以确保顺序正确。
请注意,在这种情况下,由于版本是Perl 5.12或更高版本,因此您会自动获得约束 。
您可以使用$'
捕获字符串的匹配后部分:
if ( $line =~ m/^User-Agent: / ) {
warn $';
}
(请注意,冒号后面有一个尾随空格。)
但是请注意,来自perlre :
警告:一旦Perl在程序中的任何位置看到您需要$&,$`或$'中的一个,它就必须为每个模式匹配提供它们。 这可能会大大降低您的程序速度。 Perl使用相同的机制来产生$ 1,$ 2等,因此您还为包含捕获括号的每个模式付出了代价。 (为避免在保留分组行为的同时避免这种开销,请改用扩展的正则表达式(?:...)。)但是,如果您从不使用$&,$`或$',则不捕获括号的模式将不会受到惩罚。 因此,如果可以的话,请避免使用$&,$'和$`,但如果不能(并且某些算法真的很欣赏它们),则一旦使用了它们,就可以随意使用它们,因为您已经支付了价钱。 从5.005开始,$&的价格不及其他两个昂贵。
使用$'
将字符串的一部分移到匹配项的右边。
关于“相当大的性能损失”的其他答案中有很多痛苦的话题,但是除非您实际上知道您的程序大量使用正则表达式,并且您遇到了性能问题,否则我不必担心。
我们经常担心对实际代码几乎没有影响的优化。 很有可能,这也是其中之一。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.