在perl中有效地查找所有子表达式匹配的数组

时间:2014-11-17 20:02:20

标签: regex perl

假设我有

my $xml = "<value>1</value><value>2</value><value>3</value> ... ";

我想尽可能有效地将序列1,2,3,...提取到数组@values

我知道我可以遍历所有匹配并一次构建一个数组。 我也知道,如果我想要一个包含<value>i</value>形式元素的数组,我可以使用

@values = $xml =~ m/<value>\d+?<\/value>/g;

是否有与上述相似的行来获取中间的数字?

2 个答案:

答案 0 :(得分:3)

在列表上下文中,当// g匹配没有捕获时,它返回匹配的内容。如果它已捕获,则仅返回捕获的值。

my @values = $xml =~ m{<value>(\d+)</value>}g;

答案 1 :(得分:2)

我想知道避免全局模式匹配正则表达式是否更有效:

my @values = split /<\/values><value>/, $xml;
$values[0] ~= s/<value>//;
$values[-1] ~= s/<\/value>//;

use strict;             # Lets you know when you misspell variable names
use warnings;           # Warns of issues (using undefined variables
use feature qw(say);    # Let's you use 'say' instead of 'print' (No \n needed)
use Benchmark;
use autodie;            # Program automatically dies on bad file operations

my $string = "<value>1</value><value>2</value><value>3</value><value>4</value><value>5</value><value>6</value><value>7</value><value>8</value><value>9</value><value>10</value><value>11</value><value>12</value>";

my $ref =  timethese(1_000_000, {
    Regex => \&regex,
    Split => \&split,
}
);

sub regex {
    my @values = $string =~ m{<value>(\d+)</value>}g;
};

sub split {
    my @values = split /<\/value><value>/, $string;
    $values[0] =~ s/<value>//;
    $values[-1] =~ s/<\/values>//;
}

$ test.pl   
Benchmark: timing 1000000 iterations of Regex, Split...
Split:  4 wallclock secs ( 3.68 usr +  0.01 sys =  3.69 CPU) @ 271002.71/s (n=1000000)
Regex:  8 wallclock secs ( 6.99 usr +  0.02 sys =  7.01 CPU) @ 142653.35/s (n=1000000)