我对匹配多个组的正则表达式的处理/返回数据类型有疑问。 考虑这一行:
($pre, $middle, $post) = $text =~ /(.*)Telefon:(.+)(Fax:.*)/;
我想将$ text的匹配部分的值分配给$ pre,$ middle和$ post 作为列表! 所以我想在返回的匹配数之前检查。由于返回的数据类型是一个列表,我假设以下工作:
if (scalar ($text =~ /(.*)Telefon:(.+)(Fax:.*)/) == 3) { do something }
问题似乎是那个
(scalar ($text =~ /(.*)Telefon:(.+)(Fax:.*)/)
返回1
,,但以下按预期工作(返回值3
):
my @arr = $text =~ /(.*)Telefon:(.+)(Fax:.*)/;
scalar @arr
似乎有一些Perl魔法在继续。如果不在两者之间分配值(@arr
),我该怎么做才能获得预期值?
答案 0 :(得分:4)
在perl中,与列表上下文相比,函数或运算符可以在标量上下文中返回不同的东西。事实上,即使是你自己编写的副本也可以这样做..请参阅wantarray关键字。
当在标量上下文中评估正则表达式时,它返回1表示匹配,或0表示不匹配。与列表上下文中返回的内容不同,后者是捕获组。
首先分配给数组时,将在列表上下文中评估正则表达式。然后你获取数组的标量值,它给出了长度。
无论如何,我怀疑你不会得到你想要的结果。如果正则表达式匹配,您将始终获得大小为3的列表,即使某些捕获组为空。但是,如果任何捕获组为空,则列表中的结果插槽将为undef(您可以检查)。如果正则表达式不匹配,那么你会得到一个空列表。
答案 1 :(得分:1)
我们必须为比赛提供列表上下文 - 例如通过分配列表:
() = $text =~ /.../
是的,空列表有效。我们可以在标量上下文中使用此列表赋值,例如
3 == (() = $text =~ /.../)
您可以将()=
视为“计数”伪运算符。
许多Perl运算符和内置函数的行为因上下文而异。如有疑问,请阅读documentation(尽管此特定部分将您引导至文档的其他部分)。