jessarah
jessarah

Reputation: 351

perl regex match first occurence

I have the following:

my $str='"fld":{xyz..,"val":"x"},"fldA":{afd;ladf,"val":"valid y"},"fldB":{adsa;afda,"val":"invalid val x"}...';
my $fldNm="fldA";
if ( $str =~ /"$fldNm".*"val":"([^"]+)"/ ) {
    print "\n Val = $1 \n";
}

What would be the correct regex to match/print "valid y"

The current regex matches "fldA" and greedy match and skips its value and instead gives me the last value: "invalid val x"

Thanks,

Jess

Upvotes: 0

Views: 1023

Answers (1)

Chris Doyle
Chris Doyle

Reputation: 12027

As you mentioned the .* is greedy, it will continue to swallow everything except end of line. After matching all the way to the end of the line, it will then parse the next pattern "val". since we have eaten all the way to the end of the line, the regex will now back track till it finds the first match. Since its backtracking it will match the pattern nearest the end of the line and stop since it found a match.

you need to use the non greedy quantifier .*? to tell the regex to only swallow up chars till you find the next pattern, rather than swallowing everything up and back tracking.

this is described here http://perldoc.perl.org/perlre.html under Quntifiers

By default, a quantified subpattern is "greedy", that is, it will match as many times as possible (given a particular starting location) while still allowing the rest of the pattern to match. If you want it to match the minimum number of times possible, follow the quantifier with a "?". Note that the meanings don't change, just the "greediness":

Upvotes: 2

Related Questions