反向正则表达式搜索

时间:2010-10-06 21:07:31

标签: regex perl

我有一个字符串,其中包含“foo”后跟数字。我想在字符串中的最后一个foo后打印数字。我被告知,实现这一目标的唯一方法是扭转字符串本身。这不是很优雅,我很惊讶Perl没有更好的方法来完成工作。有没有比这更好的方法呢?

#!/usr/bin/perl
# works, but is ugly!!!
$string = "foo1 foo3 foo5 bar foo911 baz";
$string = scalar reverse($string);
$string =~ m/(\d+)oof/;
print scalar reverse("$1");

3 个答案:

答案 0 :(得分:14)

怎么样:

$string =~ /.*foo(\d+)/;

澄清:

$string =~ /.*     # Match any character zero or more times, greedily.
            foo    # Match 'foo'
            (\d+)  # Match and capture one or more digits.
           /x;

贪婪的“任何角色”匹配将匹配字符串中的第一个“foo”,并且您将只留下与最后一个“foo”匹配。

示例:

#!perl -w

use strict;
use 5.010;

my $string = "foo1 foo2 foo3";
$string =~ /.*foo(\d+)/;
say $1;

输出:

% perl regex.pl
3

答案 1 :(得分:4)

我知道你已经选择了一个答案,但我想我会增加0.02美元。

为什么不进行列表上下文全局模式匹配并获取最后一个元素:

#!/usr/bin/perl

use strict;
use warnings;

my $string = "foo1 foo2 foo3 bar";
my @result = $string =~ /foo(\d+)/g;

print pop(@result) . "\n";

答案 2 :(得分:3)

这是另一个解决方案,受到ysth评论的启发(如果它是一个非常长的字符串,最后一个foo接近开头,导致正则表达式变慢):split'foo'上的行并解析最后一个数字的元素:

my @results = split /foo/, $string;
my ($digits) = ($results[-1] =~ m/^(\d+)/);

同样,我总是会使用最简单的代码,直到看起来代码花费太长时间(这在整个应用程序中是一个问题),然后我会根据典型输入对许多解决方案进行基准测试这是最好的。