Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex range operator

Tags:

regex

perl

I have a string '11 15 '. W/ a Regex I then compare the values within that string, in this case 11 and 15 (could be any number of digits but I'll keep it simple with 2 2-digit numbers).

For each of those numbers, I then see if it matches any of the numbers I want; in this case I want to see if the number is '12', '13', or '14'. If it is, then I change the value of '$m':

my $string = '11 15 ';
while ( $string =~ /([0-9]{1,})\s+/ig ) {
    my $m = $1;
    print $m . ".....";
    $m = 'change value' if $m =~ /[12...14]{2,}/g;
    print $m . "\n";
}

Produces:

11.....change value
15.....15

'15' stays the same, as it should. But '11' changes. What am I doing wrong?

like image 225
user_78361084 Avatar asked Feb 24 '23 00:02

user_78361084


2 Answers

[12...14] matches against "1", "2", ".", and "4". "11" Matches that; "15" doesn't. If you're just matching against numbers, you shouldn't be using regular expressions. Change your line to the following:

$m = 'change value' if $m ~~ [11..14];

Or, if unable to guarantee perl >= v5.10:

$m = 'change value' if grep { $m == $_ } 11..14;
like image 142
Richard Simões Avatar answered Mar 05 '23 01:03

Richard Simões


You've misunderstood the regular expression. Where you've written [12...14]{2,}, this means "match 2 or more of the characters 1 or 2 or dot or dot or dot or dot or 1 or 4".

Try something like:

$m='change value' if $m=~/(\d{2,})/ and $1 >= 12 and $1 <= 14;

In a substitution operation, this could be written as:

$m =~ s/(\d{2,})/ $1 >= 12 && $1 <= 14 ? 'change value' : $1/ge;

That is, capture 2 or more digits and then test what you have captured to see if they're what you want to change by using perl code in the replacement section of the substitution. The e modifier indicates that Perl should evaluate the replacement as Perl code.

like image 41
Adrian Pronk Avatar answered Mar 05 '23 01:03

Adrian Pronk