我有一个以下格式的字符串:_num1_num2
。我需要为某些变量分配num1
和num2
值。我的正则表达式是(\d+)
,它在Rubular.com上显示了正确的匹配组,但我不知道如何将这些匹配组分配给某些变量。有谁能够帮我?谢谢你。
答案 0 :(得分:8)
那应该是(假设你的字符串存储在'$string
'):
my ($var1, $var2) = $string =~ /_(\d+)_(\d+)/s;
我们的想法是获取数字,直到您获得非数字字符:此处为“_
”。
然后将每个捕获组分配给它们各自的变量。
正如this question(以及in the comments下面的Kaoru)所述:
如果应用于Unicode字符串,
\d
确实可以匹配10个以上的不同字符。
所以你可以改为使用:
my ($var1, $var2) = $string =~ /_([0-9]+)_([0-9]+)/s;
答案 1 :(得分:3)
使用g-modifier还可以取消分组括号:
my ($five, $sixty) = '_5_60' =~ /\d+/g;
这允许任何整数分离,但它不验证输入格式。
答案 2 :(得分:1)
在第一个答案中使用全局标志有点令人困惑。正则表达式 / _(\ d +)_(\ d +)/ 已经捕获了两个整数。此外,g修饰符尝试多次匹配。所以这是多余的。
恕我直言,当匹配数未知或简化正则表达式时,应使用g修饰符。
据我所知,这与JavaScript中的工作方式完全相同。
以下是一些例子:
use strict;
use warnings;
use Data::Dumper;
my $str_a = '_1_22'; # three integers seperated by an underscore
# expect two integert
# using the g modifier for global matching
my ($int1_g, $int2_g) = $str_a =~ m/_(\d+)/g;
print "global:\n", Dumper( $str_a, $int1_g, $int2_g ), "\n";
# match two ints explicitly
my ( $int1_e, $int2_e) = $str_a =~ m/_(\d+)_(\d+)/;
print "explicit:\n", Dumper( $str_a, $int1_e, $int2_e ), "\n";
# matching an unknown number of integers
my $str_b = '_1_22_333_4444';
my @ints = $str_b =~ m/_(\d+)/g;
print "multiple integers:\n", Dumper( $str_b, \@ints ), "\n";
# alternatively you can use split
my ( $int1_s, $int2_s ) = split m/_/, $str_a;
print "split:\n", Dumper( $str_a, $int1_g, $int2_g ), "\n";