我可以使用命名组在Perl正则表达式中将结果存储到哈希表中吗?

27

在Perl的正则表达式语法中,是否可以像Python一样执行命名组匹配?我总是在匹配后将$n值绑定到适当的名称,所以如果可能的话,在正则表达式本身中执行它会更方便。

Python的做法如下:

>>> import re
>>> regex = re.compile(r'(?P<count>\d+)')
>>> match = regex.match('42')
>>> print match.groupdict()
{'count': '42'}

我知道?P表示这是Python特定的正则表达式功能,但我希望在Perl中有不同的方式或者后来添加了此功能。是否有类似的方法可以在Perl中获得结果哈希码呢?


1
为了搜索引擎的可发现性:命名组有时也被称为“符号组名”。 - conny
5个回答

51

Perl使用(?<NAME>pattern)来指定命名捕获。您需要使用%+哈希表来检索它们。

$variable =~ /(?<count>\d+)/;
print "Count is $+{count}";

尽管如此,这仅在Perl 5.10及更高版本上受支持。


4
你也可以使用%-来访问捕获的内容。 - Brad Gilbert
1
此答案已添加到Stack Overflow正则表达式FAQ,位于“分组”下。 - aliteralmind
你的意思是要说:“你必须使用$+哈希来检索它们”,对吗? - undefined
不,我指的是%+,但是inflection意味着你通过$+{key}来访问它的成员。这是Perl的一个特性,让很多外行人感到困惑。 - undefined

21
自Perl 5.10起,Perl正则表达式支持一些Python特性,使它们成为Python兼容的正则表达式。Python版本中有一个“P”,但所有这些都适用于Perl 5.10。有关详细信息,请参见perlre文档:
定义一个命名捕获缓冲区。相当于(?<NAME>pattern)
(?P<NAME>pattern)

指向已命名捕获缓冲区的反向引用。等同于\g{NAME}

(?P=NAME)

调用命名捕获缓冲区的子例程。相当于(?&名称)

(?P>NAME)

虽然我没有在学习Perl的最新版本中添加Python兼容性,但我们确实涵盖了新的Perl 5.10功能,包括命名捕获。


1
请明确哪个是Perl语法,哪个是Python。 - ysth
带有额外P的语法是Python。 - Leon Timmermans
我已经尝试了它们所有,看看哪些适用于Perl。 是的,它们都可以在最新的Perl中使用。 - Aftershock

13

正如一些人所说,Perl 5.10有命名组。

但在以前的Perl版本中,你也可以做一些事情,虽然不太方便,但相对不错:

my %hash;
@hash{"count", "something_else"} = $string =~ /(\d+)\s*,\s*(\S+)/;

然后你可以使用:

$hash{"count"} 和 $hash{"something_else"}。


5
据我所知,PCRE 把命名组捕获称为:
(?'NAME'pattern)
(?<NAME>pattern)

您可以在此处查找相关信息。

0

我使用%{^CAPTURE}哈希表(为了可读性)。

这是由Leon Timmermans上面提到的%+英文版本。

例如,我编写的用于捕获PHP版本的代码:

#! /usr/bin/env perl

use v5.32;
use warnings;
use English;

my $output = `php -v`;

$output =~ m(PHP (?<version>\d.\d.\d\d)); # named capture group

say ${^CAPTURE}{version}; # instead of $1

在正则表达式模式中,你可以通过\g{NAME}来引用已命名的捕获组。

TIMTOWTDI在Perl中适用,所以使用最适合你的那个。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接