Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl6 assign regex match groups to variables

Tags:

regex

raku

In P5, I am able to do something like this

my ($var1, $var2, $var3) = $string =~ /(.+)\s(.+)\s(.+)/;

How do I do the same in Perl 6? If I do the same syntax, the $var1 will hold the entire $string value.

like image 468
Zarul Zakuan Avatar asked Nov 25 '18 02:11

Zarul Zakuan


People also ask

How do groups work in regex?

What is Group in Regex? A group is a part of a regex pattern enclosed in parentheses () metacharacter. We create a group by placing the regex pattern inside the set of parentheses ( and ) . For example, the regular expression (cat) creates a single group containing the letters 'c', 'a', and 't'.

What is the meaning of $1 in Perl regex?

$1 equals the text " brown ".

How do I match a string in regex in Perl?

Simple word matching In this statement, World is a regex and the // enclosing /World/ tells Perl to search a string for a match. The operator =~ associates the string with the regex match and produces a true value if the regex matched, or false if the regex did not match.


2 Answers

The result from that match is a Match object, which by itself won't behave like a list, and therefore won't expand into the three variables. However, the Match object has a "list" method that does what you want. Here's an example:

my $string = "hello how are you";
my ($var1, $var2, $var3) =
    ($string ~~ /(.+)\s(.+)\s(.+)/).list;
say "$var1 and $var2 and $var3
# Output: hello how and are and you

A few further things to point out:

  • Since .+ is a greedy match, and it also accepts spaces, the first capture will eat up two words.
  • Surely the code in the question is a simplified example, but if you ever need to split text into words, maybe the words method does what you want. Of course, you'll want to check what exactly you want: Split by spaces? Only return alphabetic characters, so that periods and commas aren't in the final result? etc.
  • If you do need to match the same thing multiple times, maybe the comb method is actually more helpful?
like image 51
timotimo Avatar answered Sep 20 '22 23:09

timotimo


my $string = 'foo bar baz';

my $match = $string ~~ /(.+)\s(.+)\s(.+)/;
say $match;     # 'foo bar baz'
say $match[0];  # 'foo'
say $match[1];  # 'bar'
say $match[2];  # 'baz'

my ($foo, $bar, $baz) = @$match;
say $foo;       # 'foo'
say $bar;       # 'bar'
say $baz;       # 'baz'

therefore

my ($foo, $bar, $baz) = @($string ~~ /(.+)\s(.+)\s(.+)/);
like image 29
Tomalak Avatar answered Sep 20 '22 23:09

Tomalak