Re: Regex replacement via external command

Discussion in 'Perl Misc' started by Rainer Weikusat, Jan 23, 2014.

  1. * Tong * <> writes:
    > On Wed, 22 Jan 2014 16:27:56 +0000, Rainer Weikusat wrote:
    >>> Another approach (as always) would be temporary files.

    >>
    >> In case the program is really supposed to work as a filter, a possible
    >> other aproach would be to use a 'Perl lexer', eg, for the example above,
    >> assuming the input is in $s (untested)
    >>
    >> for ($s) {
    >> /\G(x+)/gc and do {
    >> my $fh;
    >>
    >> open($fh, '|command');
    >> print $fh ($1);
    >> $fh = undef;
    >>
    >> redo;
    >> };
    >>
    >> /\G([^x]+)/gc and print($1), redo;
    >> }
    >>
    >> and simply let the output of the external command appear 'in the right
    >> place' of the stdout output of the perl script (since they'll share the
    >> same stdout).

    >
    > This would be quite a mouthful for me. I have to try it out so as to
    > understand exactly what's going on.
    >
    > But first, a quick question, this looks to me like a filter program in
    > Perl, that writes out matches ($1) itself, and uses external command to
    > further processing the matches ($1) as well. The external command take
    > the match string from pipe input, and writes out its result in the right
    > place of the stdout output, correct? I.e., both the Perl script and the
    > external command write their output to stdout, correct?
    >
    > The problem for me is that I not only need to process this big chunk of
    > matching string via the external program, but I also need to replace the
    > matching string with the result of the external process as well. The
    > above code doesn't take care of grabbing the output of the external
    > command and use it as the replacement, correct?


    Contrived example which can actually be executed:

    -----------------
    undef $/;
    my $input = <STDIN>;

    for ($input) {
    /\G(x+)/gc and do {
    my $fh;

    open($fh, '| tr x y');
    print $fh ($1);

    redo;
    };

    /\G([^x]+)/g and print($1), redo;
    }
    -----------------

    This will read data from stdin until EOF. Any x in the input is replaced
    with an y by piping it through 'tr x y', anything else is just printed
    as-is. The for-'loop' is an extremely simple example of how to write a
    lexical analyzer in Perl:

    The first regex looks for a sequences of x at the current matching
    position (\G, initially 0). If it matches, a pipe to tr is opened and
    the matched text written to that. The 'redo' than cause the loop body to
    be executed again. The /g flag means 'match globally', ie, find all
    occurences, not just the first one, and the /c means 'don't reset the
    current matching position in case the match fails'.

    The second regex matches a sequences of 'something other than x': If it
    matches, the matched text is printed and the loop body re-executed via
    redo. The /c flag is not needed for the 2nd match because if neither the
    first nor the second regex matched, end of the input has obviously been
    reached, and the loop terminates.
    Rainer Weikusat, Jan 23, 2014
    #1
    1. Advertising

  2. Rainer Weikusat <> writes:

    [...]


    > Contrived example which can actually be executed:
    >
    > -----------------
    > undef $/;
    > my $input = <STDIN>;
    >
    > for ($input) {
    > /\G(x+)/gc and do {
    > my $fh;
    >
    > open($fh, '| tr x y');


    This is sort-of a silly example pipe because the output would be
    identical when everything was just piped through tr. A slightly less
    silly example would be

    open($fh, '| sed "s/./y/g"');

    This uses sed to replace every input byte with an y. As can easily be
    verified, it only runs for x in the input, not for any other character.
    Rainer Weikusat, Jan 23, 2014
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    746
    Reedick, Andrew
    Jul 1, 2008
  2. Anthony Roy
    Replies:
    7
    Views:
    214
    A. Sinan Unur
    Mar 4, 2005
  3. Rainer Weikusat

    Re: Regex replacement via external command

    Rainer Weikusat, Jan 22, 2014, in forum: Perl Misc
    Replies:
    2
    Views:
    76
    Rainer Weikusat
    Jan 23, 2014
  4. George Mpouras

    Re: Regex replacement via external command

    George Mpouras, Jan 22, 2014, in forum: Perl Misc
    Replies:
    0
    Views:
    87
    George Mpouras
    Jan 22, 2014
  5. Charles DeRykus

    Re: Regex replacement via external command

    Charles DeRykus, Jan 23, 2014, in forum: Perl Misc
    Replies:
    2
    Views:
    64
    Charles DeRykus
    Jan 23, 2014
Loading...

Share This Page