1

In Ruby you can extract the named captured groups of a regex using the namesmethod:

/(?<foo>.)(?<bar>.)(?<baz>.)/.names
#=> ["foo", "bar", "baz"]

Is there a Perl equivalent for such method? I could extract the names doing something like this:

while ( $re =~ m/\?<(.+?)>/g ) {
    say $1;
}

But I don't know how robust/efficient/elegant that solutions is.

EDITED: I know that you can get the names after a match but I need to extract the names before using the regex.

abjY6U54
  • 13
  • 3

2 Answers2

4

You can extract the names of the groups after a successful match:

my $re = qr/(?<foo>.)(?<bar>.)(?<baz>.)/;
'abc' =~ $re;
say for keys %-;

See also Tie::Hash::NamedCapture.

choroba
  • 231,213
  • 25
  • 204
  • 289
  • Hang on, isn't it `%+`? – simbabque Mar 28 '18 at 11:56
  • Oh. perlvar has the difference. – simbabque Mar 28 '18 at 11:57
  • I need to extract the names without having to match the regex – abjY6U54 Mar 28 '18 at 12:02
  • 2
    @abjY6U54: If you think you need to know the names of capture groups in a regex pattern that hasn't been applied to a string then you need to think again. It's something that can't be done in Perl, and with good reason. The values are available only after a *successful* match in the current lexical scope. – Borodin Mar 28 '18 at 12:13
2

See PPIx::Regexp::capture_names:

foreach my $name ( $re->capture_names() ) {
      print "Capture name '$name'\n";
 }

This convenience method returns the capture names found in the regular expression.

I have not tried this module, so I am not sure if it is a 100% reliable way extracting the information you want.

See also @ikegami's answer to this question which led me to re-read perldoc re:

regnames($all)

Returns a list of all of the named buffers defined in the last successful match. If $all is true, then it returns all names defined, if not it returns only names which were involved in the match.

So close, yet not quite. I am not aware of a builtin way of doing introspection on regular expression patterns in Perl in the way Ruby's .names does.

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339