全局正则表达式替换和存储

时间:2013-12-23 08:12:39

标签: regex perl

我需要替换某些模式的所有匹配项并将其旧值保存到数组中。我可以通过两种方式管理它:

#!/usr/bin/perl -w

@num = ();

$_ = "We had 2 bags of grass, 75 pellets of mescaline, 
5 sheets of high powered blotter acid, a salt shaker 0.5 full of cocaine,
and a 1.0 galaxy of multi-colored uppers, downers, screamers, laughers...
and also a 0.25gal of tequila, a 0.25gal of rum, a case of Budweiser,
a 0.125gal of raw ether and 24 amyls.";

s/\d+(\.\d*)?/push(@num, $&)/ge;  # Step 1: Store
s/\d+(\.\d*)?/some/g;             # Step 2: Replace

print "@num";                     # 2 75 5 0.5 1.0 0.25 0.25 0.125 24
print "$_";                       # We had some bags of grass, ...

但我相信它并不好:实际上,相同的代码被输入两次。我更喜欢单个正则表达式来解决问题。这在Perl中可能吗?

2 个答案:

答案 0 :(得分:4)

你一直用push(Returns the number of elements in the array following the completed push.)的返回值代替,所以你需要替换最后一个表达式。

s/\d+(\.\d*)?/ push(@num, $&); "some" /ge;

旁注;作为$& imposes a performance penalty你也可以

s/(\d+(?:\.\d*)?)/ push(@num, $1); "some" /ge;

答案 1 :(得分:1)

正如您将看到的,正则表达式右侧的最后一个语句是用于替换的语句。

#!/usr/bin/perl -w

use strict;
use warnings;

my @nums = ();

my $text = "We had 2 bags of grass, 75 pellets of mescaline, 
5 sheets of high powered blotter acid, a salt shaker 0.5 full of cocaine,
and a 1.0 galaxy of multi-colored uppers, downers, screamers, laughers...
and also a 0.25gal of tequila, a 0.25gal of rum, a case of Budweiser,
a 0.125gal of raw ether and 24 amyls.";

$text =~ s{(\d+\.?\d*)}{
    push(@nums, $1);
    "some"
}ge;

print "@nums\n";                     # 2 75 5 0.5 1.0 0.25 0.25 0.125 24
print "$text";