Recover groups of a regular expression in Perl

Asked

Viewed 300 times

7

I am running this regular expression to separate the digits of a version:

([\d]+)+

As you can see in this example, it works well enough to cover my needs.

However, I have to add this treatment in a Perl script, which is not by far my specialty. I run my regex and then try to recover group values.

$version="2.2.1-ALPHA30";
$version=~/([\d]+)+/g;
print "major:$1 minor:$2 revision:$3 build:$4\n"

First I only have $1 that is shown, the others are empty.

And finally, I see no way of knowing how many values were found by the regex.

  • 1

    I updated the answer, did not see that you needed to know also the amount of numbers found.

  • 1

    I need the amount so I can treat further and manage the degraded cases

3 answers

4


In the expression ([\d]+)+ no bracket is required, nor the second addition operator. If you need to put the results in a array to count the number of occurrences found, do:

$version="2.2.1-ALPHA30";
my @numeros = $version =~ /(\d+)/g;
$quantidade = scalar(@numeros);

print "Foram encontrados $quantidade números!\n";
print join(", ", @numeros);

DEMO

If you need to know the number of occurrences and need to work individually with each one, assign each variable a capture:

$version="2.2.1-ALPHA30";;
my $quantidade = () = my ($major, $minor, $revision, $build) = $version =~ /(\d+)/g;

print "Foi encontrado $quantidade resultados!\n";
print "$major, $minor, $revision, $build\n";

DEMO

3

The previous answers already say everything... One thing I like about Perl is that regular expressions match well with control structures: catches and control structures

Capture groups produce lists when used in list context (as stated earlier)

@r = $version =~ m/(\d+)/g;

and return True/False in Boolean context. These implicit conversions
can be used in various control structures (untested):
(1) if

$p = "stardict_3.0.4-1"
if($p =~ m/(.*?)_(\d+[.\d-]*)/ ) {  
    print "base=$1   version=$2 }

(2) for

$t="era uma vez um gato maltez";
for($t =~ m/(\w+)/g) { 
    $ocorrencia{$_}++ }

(3)while

$ls=`ls`;
while($ls =~ m/(\S+?)\.(\w+)/g ){ 
   print "nome=$1; extensao:$2\n"}

(4)s/expressãoregular/ perl /e

$text= "volto amanha";
$text =~ s/amanha/ `date --date="tomorrow"` /ge

1

Try it this way:

$version="2.2.1-ALPHA30";
my @resultados = $version=~/([\d]+)+/g;
print join(", ", @resultados);

I only used print to show all the results that were captured. You can use the array to access each of the results.

If you just want the number you can use the array to scale.

  • Good! Having the array I get the scalar(@resultados) to have the amount of numbers found.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.