Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 为什么$1在一个hashref赋值中指向几个正则表达式匹配的相同值?_Regex_Perl - Fatal编程技术网

Regex 为什么$1在一个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,

对于没有故事的问题,请跳到行后

我在胡闹,把一个字母和数字串(这两个字母和数字都可能出现)拆分成一个hashref中的两个字段。仅当该字段存在时,它们才应出现。字符串可能如下所示:
/^\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
解决方案更好/更有效。没关系,我也没有试图给出解决方案,只是想说明问题所在,因为这就是问题所在:)你是对的。我就是这么问的。毕竟,你应该得到接受。:)