问题描述
我想在字符串中搜索给定的字符并返回它后面的字符。
根据这里的帖子,我尝试写作
my $string = 'v' . '2';
my $char = $string =~ 'v'.{0,1};
print $char;
但这会返回 1 和一个哈希值(我上次运行它时,确切的输出是 1HASH(0x11823a498))。有谁知道为什么它返回一个散列而不是字符?
解决方法
返回特定模式后的字符(此处为字符)
my $string = 'example';
my $pattern = qr(e);
my ($ret) = $string =~ /$pattern(.)/; #--> 'x'
这匹配 $pattern
中第一次出现的 $string
,并捕获并返回下一个字符 x
。 (该示例不处理可能没有字符跟随的情况,例如其他 e
;它只会无法匹配,因此 $ret
将保持 undef
。)
我使用 qr 操作符来形成一个模式,但一个普通的字符串在这里也可以。
正则表达式匹配运算符在标量和列表 contexts 中返回不同的东西:在标量上下文中它是否匹配是真/假,而在列表上下文中它返回匹配。见perlretut
因此,您需要在列表上下文中进行匹配,而提供该匹配项的常用方法是将要分配给的变量放在括号中。
问题中示例的第一个问题是=~
运算符binds比.
运算符更紧密,因此示例有效
my $char = ( ($string =~ 'v') . {0,1} );
所以首先是正则表达式匹配,它成功并返回 1
(因为它在标量上下文中,由 .
运算符强加)然后有一个散列引用 {{1} } 连接到那个 {0,1}
。所以 1
被分配了 $char
与一个 hashref 的字符串化连接,它是一个字符串 1
(在括号中是一个地址的十六进制字符串化)。
接下来,模式中所需的 HASH(0x...)
不存在。对连接 .
运算符感到困惑?
然后,捕获括号不存在,但需要用于预期的子模式。
最后,匹配的是标量上下文,如上所述,只会产生真/假。
总而言之,应该是
.
但我想补充一点:虽然 Perl 具有非常流畅的语义,但我建议不要像那样即时构建正则表达式模式。为了清楚起见,我还建议您在匹配运算符中实际使用分隔符(即使您确实大多数情况下不必这样做)。