Regex 为什么$1在一个hashref赋值中指向几个正则表达式匹配的相同值?
对于没有故事的问题,请跳到行后 我在胡闹,把一个字母和数字串(这两个字母和数字都可能出现)拆分成一个hashref中的两个字段。仅当该字段存在时,它们才应出现。字符串可能如下所示:Regex 为什么$1在一个hashref赋值中指向几个正则表达式匹配的相同值?,regex,perl,Regex,Perl,对于没有故事的问题,请跳到行后 我在胡闹,把一个字母和数字串(这两个字母和数字都可能出现)拆分成一个hashref中的两个字段。仅当该字段存在时,它们才应出现。字符串可能如下所示:/^\D*\D*$/,例如ZR17,R15,-19,22 我不想简单地将其放入两个变量中,因为实际的hashref稍长一些,我想将内容分组在一起 my $asdf = "ZR17"; my ($x, $y) = $asdf =~ m/^(\D*)(\d*)$/; my $foo = { foo => $x,
/^\D*\D*$/
,例如ZR17
,R15
,-19
,22
我不想简单地将其放入两个变量中,因为实际的hashref稍长一些,我想将内容分组在一起
my $asdf = "ZR17";
my ($x, $y) = $asdf =~ m/^(\D*)(\d*)$/;
my $foo = {
foo => $x,
bar => $y
};
如果我不想在字符串17
的情况下使用键foo
,我可以说:
my $foo = {
( $x ? ( foo => $x ) : () ),
( $y ? ( bar => $y ) : () ),
};
我想把它全部放在hashref作业中,如下所示:
my $asdf = "ZR17";
my $foo = {
( $asdf =~ m/(\d+)/ ? ( foo => $1 ) : () ),
( $asdf =~ m/(\D+)/ ? ( bar => $1 ) : () ),
};
print Dumper $foo;
这将产生以下结果:
$VAR1 = {
'bar' => 'ZR',
'foo' => 'ZR'
};
不知何故,这里似乎只有一个$1
,它被搞混了。如果我走出第二行,foo
将是17
有人能解释一下这里发生了什么吗哪里是
$1
丢失/混淆了?对于foo
和bar
来说,它看起来像$1
是来自上一个正则表达式匹配
my $asdf = "ZR17";
my $foo = {
( $asdf =~ m/(\D+)/ ? ( bar => $1 ) : () ),
( $asdf =~ m/(\d+)/ ? ( foo => $1 ) : () ),
};
print Dumper $foo;
输出
$VAR1 = {
'bar' => '17',
'foo' => '17'
};
$VAR1 = {
'bar' => 'ZR',
'foo' => '17'
};
然而,这是意料之中的事
my $foo = {
( map { (bar => $_) } $asdf =~ m/(\D+)/ ),
( map { (foo => $_) } $asdf =~ m/(\d+)/ ),
};
输出
$VAR1 = {
'bar' => '17',
'foo' => '17'
};
$VAR1 = {
'bar' => 'ZR',
'foo' => '17'
};
根据perldoc():
因此,$1在$asdf=~m/(\d+)/之后被覆盖为17,因为它找到了一个匹配项,但尚未遇到封闭块的结尾
然而,
my $foo = {
( eval{$asdf =~ m/(\D+)/ ? ( bar => $1 ) : ()} ),
( eval{$asdf =~ m/(\d+)/ ? ( foo => $1 ) : ()} ),
};
将在作用域分开时给出预期结果。Perl 5.10+将允许您使用,这基本上就是您想要做的。任何不匹配的捕获组都将存储在中,并将
“
作为您案例中的值:
use strict;
use warnings;
use Data::Dump 'dd';
my $asdf = "ZR17";
$asdf =~ m/^(?<alpha>\D*)(?<num>\d*)$/;
my $foo = { map { $+{$_} ? ( $_ => $+{$_} ) : () } keys %+ };
dd $foo; # { alpha => "ZR", num => 17 }
使用严格;
使用警告;
使用数据::转储'dd';
我的$asdf=“ZR17”;
$asdf=~m/^(?\D*)(?\D*)$/;
我的$foo={map{$+{$}?($\=>$+{$}):()}键%+};
dd$foo;#{alpha=>“ZR”,num=>17}
我猜三元运算符在返回(bar=>$1)
和(foo=>$1)
时不会计算$1
。因此,在中间步骤中,您可以
$foo = { ( bar => $1 ), ( foo => $1 ) };
由于$1
现在是第二次匹配操作的捕获子字符串,因此$foo{bar}
和$foo{foo}
的值相同
实现所需的另一种方法(即,如果未找到相应的匹配项,则哈希元素不存在):
当您需要匹配更多模式时,可以扩展
%patt
。我正在寻找perldoc的那部分,但没有看到它。谢谢。顺便说一句,回答得很好。我没有接受它,因为我认为map
解决方案更好/更有效。没关系,我也没有试图给出解决方案,只是想说明问题所在,因为这就是问题所在:)你是对的。我就是这么问的。毕竟,你应该得到接受。:)