Jessarah FL has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, I have this
my $str='"fld":{xz.,"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 print "valid y"

The current regex matches "fldA" but then skips its actual val and instead gives me the last val value.

Thanks, Jess

Replies are listed 'Best First'.
Re: Regex non-greedy match
by toolic (Bishop) on Oct 11, 2013 at 13:06 UTC
    Change .* to .*?
    my $str='"fld":{xz.,"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"; }
      thanks :)
Re: Regex non-greedy match
by ww (Archbishop) on Oct 11, 2013 at 13:22 UTC
    Correct answer above; explanation here:

    Your regex uses .*. Expressed in language other than the technically correct form what you'll find (and you should) in perldoc perlretut and friends: that's a 'greedy' form -- it matches anything, any number of times, until it gets to the LAST data which would match the NEXT element in the regex. The addition of the ? changes the rule -- in this case, to match anything any number of times but AS FEW AS POSSIBLE before any instance of the NEXT element in the regex.

    Hope this helps.

Re: Regex non-greedy match (JSON)
by Anonymous Monk on Oct 11, 2013 at 13:07 UTC

    Looks like JSON, don't forget about JSON or its kind (Mojo::JSON...) to decode ... :)