in reply to greedy subexpression between two nongreedy ones

s/,(?:.*?(cd))?.*?,/=$1=/

Replies are listed 'Best First'.
Re^2: greedy subexpression between two nongreedy ones
by AnomalousMonk (Archbishop) on Jun 02, 2015 at 05:46 UTC

    Although this may be perfectly acceptable,  $1 will be undefined if it is not present in the string being searched:

    c:\@Work\Perl\monks>perl -wMstrict -le "for my $s (',abcdefg,pqrstuv', ',abefg,pqrstuv', @ARGV) { my $t = $s; print qq{'$t'}; $t =~ s/,(?:.*?(cd))?.*?,/=$1=/; print qq{'$t' \n}; } " ',abcdefg,pqrstuv' '=cd=pqrstuv' ',abefg,pqrstuv' Use of uninitialized value $1 in concatenation (.) or string at -e lin +e 1. '==pqrstuv'


    Give a man a fish:  <%-(-(-(-<

      s/,(?:.*(cd))?.*,/$1 ? "=$1=" : "=="/e

        I see now my problem statement was a little sloppy: I failed to use the same sample text in my first two examples. Namely, I inadvertently omitted the trailing comma in the first example.

        And sure enough, the answer above (or rather, the three variations on the answer) works on the incorrect example, but still fails on the correct one.

        $ echo ,abcdefg,abcdefg | perl -pe 's/,(?:.*?(cd))?.*?,/=$1=/' =cd=abcdefg $ echo ,abcdefg,abcdefg, | perl -pe 's/,(?:.*?(cd))?.*?,/=$1=/' =cd=abcdefg,
        works either way when the "cd" appears between the first two anchors, but if it doesn't:
        $ echo ,abcefg,abcdefg | perl -pe 's/,(?:.*?(cd))?.*?,/=$1=/' ==abcdefg $ echo ,abcefg,abcdefg, | perl -pe 's/,(?:.*?(cd))?.*?,/=$1=/' =cd=
        it gives me what I'm looking for only when the final "," is missing. With it, the expression goes back to running past the anchor and stealing from the next blob of text.

        I need to study the answer below to see if it does what I need, but I had high hopes for the ones above, because I like their simplicity. :-)