kulan
kulan

Reputation: 1391

Perl assign regex match groups to variables

I'have a string in a following format: _num1_num2. I need to assign num1 and num2 values to some variables. My regex is (\d+) and it shows me the correct match groups on Rubular.com, but I don't know how to assign these match groups to some variables. Can anybody help me? Thanks in adv.

Upvotes: 6

Views: 8077

Answers (3)

VonC
VonC

Reputation: 1324337

That should be (assuming your string is stored in '$string'):

my ($var1, $var2) = $string =~ /_(\d+)_(\d+)/s; 

The idea is to grab numbers until you get a non-number character: here '_'.

Each capturing group is then assign to their respective variable.


As mentioned in this question (and in the comments below by Kaoru):

\d can indeed match more than 10 different characters, if applied to Unicode strings.

So you can use instead:

my ($var1, $var2) = $string =~ /_([0-9]+)_([0-9]+)/s; 

Upvotes: 12

Richard RP
Richard RP

Reputation: 525

Using the g-modifier also allows you to do away with the the grouping parenthesis:

my ($five, $sixty) = '_5_60' =~ /\d+/g;

This allows any separation of integers but it doesn't verify the input format.

Upvotes: 3

BarneySchmale
BarneySchmale

Reputation: 780

The use of the global flag in the first answer is a bit confusing. The regex /_(\d+)_(\d+)/ already captures two integers. Additionally the g modifier tries to match multiple times. So this is redundant.

IMHO the g modifier should be used when the number of matches is unknown or when it simplifies the regex.

As far as I see this works exactly the same way as in JavaScript.

Here are some examples:

use strict;
use warnings;

use Data::Dumper;

my $str_a = '_1_22'; # three integers seperated by an underscore

# expect two integert

# using the g modifier for global matching
my ($int1_g, $int2_g) = $str_a =~ m/_(\d+)/g;
print "global:\n", Dumper( $str_a, $int1_g, $int2_g ), "\n";

# match two ints explicitly
my ( $int1_e, $int2_e) = $str_a =~ m/_(\d+)_(\d+)/;
print "explicit:\n", Dumper( $str_a, $int1_e, $int2_e ), "\n";

# matching an unknown number of integers
my $str_b = '_1_22_333_4444';
my @ints = $str_b =~ m/_(\d+)/g;
print "multiple integers:\n", Dumper( $str_b, \@ints ), "\n";

# alternatively you can use split
my ( $int1_s, $int2_s ) = split m/_/, $str_a;
print "split:\n", Dumper( $str_a, $int1_g, $int2_g ), "\n";

Upvotes: 1

Related Questions