Berkeley CSUA MOTD:Entry 30393
Berkeley CSUA MOTD
 
WIKI | FAQ | Tech FAQ
http://csua.com/feed/
2025/05/25 [General] UID:1000 Activity:popular
5/25    

2004/5/24-25 [Computer/SW/Languages/Perl] UID:30393 Activity:moderate
5/24    Perl question:
        I have a match m/foo(.*?)bar(.*?)baz/;
        I want to format that into an output like "output $0,$1\n";
        But I also want it generic for different patterns, so I can say:
        $pattern = "m/foo(.*?)bar(.*?)baz/";
        $output = 'output $0,$1\n';
        while ($input =~ m/$pattern/ig)
        {
          #put use current $0,$1 in $output here somehow
        }
        What's a good way to do this?
        \_ Not sure if this is what you want, but it's an idea:
        $input2 = $input; # make a copy
        while ($input2 =~ s/$pattern/$0:$1/ig) { # extract $0 & $1
          ($var1, $var2) = split($input2, ":");
          sprintf($output, $formatString, $var1, $var2);
        }
        \_ while ( $input =~ m/"$pattern"/ig)
           # will get perl to expand $pattern before using it in the test
           \_ The matching is working fine.  That's not the question. -op
           \_ You don't need ""s
        \_ This modifies $input2 on the first pass, and with multiple matches
           in the string (note the /g option) this will return wonkey results.
           -op
           \_ This works:
              $pattern = 'foo(.*?)bar(.*?)baz'
              $text = "foo1bar2baz\nfoo3bar4baz\nfoo5bar6baz\n"
              while ($text =~m/$pattern/ig) { print "$1, $2\n"}

              Part of your problem might be that $n references starts at 1, not
              0. --scotsman
              \_ Oops.  I screwed up when typing it up in the motd.  In my
                 original code it's $1 and $2, not $0 and $1.  I've corrected
                 it above.  But the point is I want the output string formatted
                 as well.  Like:
                 $output = 'The $1 is a result of $2.';
                 or
                 $output = 'I won't $1 before $2 o'clock.';
                 -op
                 \_ okay then, replace "print" with "$output=".  Wait.  I'm
                    misreading.  Gimme a sec.  Ah. sprintf will do what
                    you want.  --scotsman
                    \_ No it won't, at least not if I don't know the number of
                       matches ahead of time.  This DOES work though:
                       $output = eval qq{sprintf qq{$format}; };
                       -op
                       \_ And there ya go.
                          \_ Thanks for the suggestions BTW. The sprintf turns
                             out to be superfluous.  This works too:
                             $output = eval qq{ qq{$format}; };