Can I use named groups in a Perl regex to get the results in a hash?
Question:
Is it possible to perform a named-group match in Perl’s regex syntax as with Python’s? I always bind the $n
values to proper names after matching, so I’d find it more convenient to do it in the regex itself if it’s possible.
Python does it like so:
>>> import re
>>> regex = re.compile(r'(?P<count>d+)')
>>> match = regex.match('42')
>>> print match.groupdict()
{'count': '42'}
I know the ?P
indicates that it’s a Python-specific regex feature, but I’m hoping it’s in Perl in a different way or was added later on. Is there any way to get a result hash in a similar manner in Perl?
Answers:
Perl uses (?<NAME>pattern)
to specify names captures. You have to use the %+
hash to retrieve them.
$variable =~ /(?<count>d+)/;
print "Count is $+{count}";
This is only supported on Perl 5.10 and higher though.
As of Perl 5.10, Perl regexes support some Python features, making them Python compatible regexes, I guess. The Python versions have the “P” in them, but all of these work in Perl 5.10. See the perlre documentation for the details:
Define a named capture buffer. Equivalent to (?<NAME>pattern)
.
(?P<NAME>pattern)
Backreference to a named capture buffer. Equivalent to g{NAME}
.
(?P=NAME)
Subroutine call to a named capture buffer. Equivalent to (?&NAME)
.
(?P>NAME)
Although I didn’t add the Python-compatibility to the latest edition of Learning Perl, we do cover the new Perl 5.10 features, including named captures.
As couple of people said perl 5.10 has named groups.
But in previous perls you can do something, not as convenient, but relatively nice:
my %hash;
@hash{"count", "something_else"} = $string =~ /(d+)s*,s*(S+)/;
and then you can use:
$hash{“count”} and $hash{“something_else”}.
I use the %{^CAPTURE}
hash (for readability).
It is English version for %+
as mentioned above by Leon Timmermans.
For example, a code I wrote for capturing PHP version:
#! /usr/bin/env perl
use v5.32;
use warnings;
use English;
my $output = `php -v`;
$output =~ m(PHP (?<version>d.d.dd)); # named capture group
say ${^CAPTURE}{version}; # instead of $1
TIMTOWTDI with Perl, so use the one which suits you the best.
Is it possible to perform a named-group match in Perl’s regex syntax as with Python’s? I always bind the $n
values to proper names after matching, so I’d find it more convenient to do it in the regex itself if it’s possible.
Python does it like so:
>>> import re
>>> regex = re.compile(r'(?P<count>d+)')
>>> match = regex.match('42')
>>> print match.groupdict()
{'count': '42'}
I know the ?P
indicates that it’s a Python-specific regex feature, but I’m hoping it’s in Perl in a different way or was added later on. Is there any way to get a result hash in a similar manner in Perl?
Perl uses (?<NAME>pattern)
to specify names captures. You have to use the %+
hash to retrieve them.
$variable =~ /(?<count>d+)/;
print "Count is $+{count}";
This is only supported on Perl 5.10 and higher though.
As of Perl 5.10, Perl regexes support some Python features, making them Python compatible regexes, I guess. The Python versions have the “P” in them, but all of these work in Perl 5.10. See the perlre documentation for the details:
Define a named capture buffer. Equivalent to (?<NAME>pattern)
.
(?P<NAME>pattern)
Backreference to a named capture buffer. Equivalent to g{NAME}
.
(?P=NAME)
Subroutine call to a named capture buffer. Equivalent to (?&NAME)
.
(?P>NAME)
Although I didn’t add the Python-compatibility to the latest edition of Learning Perl, we do cover the new Perl 5.10 features, including named captures.
As couple of people said perl 5.10 has named groups.
But in previous perls you can do something, not as convenient, but relatively nice:
my %hash;
@hash{"count", "something_else"} = $string =~ /(d+)s*,s*(S+)/;
and then you can use:
$hash{“count”} and $hash{“something_else”}.
I use the %{^CAPTURE}
hash (for readability).
It is English version for %+
as mentioned above by Leon Timmermans.
For example, a code I wrote for capturing PHP version:
#! /usr/bin/env perl
use v5.32;
use warnings;
use English;
my $output = `php -v`;
$output =~ m(PHP (?<version>d.d.dd)); # named capture group
say ${^CAPTURE}{version}; # instead of $1
TIMTOWTDI with Perl, so use the one which suits you the best.