in reply to Re: Match a pattern only if it is not within another pattern
in thread Match a pattern only if it is not within another pattern

Nice, but it only works with bar then foo then qux, not qux then foo then bar. (Following passes first test, fails second test.)
use strict; use warnings; use Test::More qw(no_plan); my $str = 'blfoo and barthisfoothatqux and barsofooquxhim andfoosom fo +o'; my $expected = 'bl123 and barthisfoothatqux and barsofooquxhim and123s +om 123'; $str =~ s[(bar.+?qux)|(foo)][defined $2 ? '123' : $1]xge; is($str,$expected); #switch qux and bar $str = 'blfoo and quxthisfoothatbar and barsofooquxhim andfoosom foo'; $expected = 'bl123 and barthisfoothatqux and barsofooquxhim and123som +123'; $str =~ s[(bar.+?qux)|(foo)][defined $2 ? '123' : $1]xge; is($str,$expected);
I'm trying to solve the more "general" problem with parse::recdescent, further on in the thread. I gave up before finding a solution though.

Replies are listed 'Best First'.
Re^3: Match a pattern only if it is not within another pattern
by xdg (Monsignor) on Aug 17, 2005 at 13:33 UTC

    If you want to learn to solve the general problem, the book "Mastering Regular Expressions" is highly recommended. If you want a solution to the general problem, Regexp::Common::balanced does it already.

    # note, this matches "qux foo bar" and "bar foo qux", but not "bar foo + bar" # see Regexp::Common::balanced documentation for details qr/$RE{balanced}{-begin => "qux|bar"}{-end => "bar|qux"}/

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re^3: Match a pattern only if it is not within another pattern
by BrowserUk (Patriarch) on Aug 17, 2005 at 17:26 UTC

    That's "Working as designed".

    Would you expect to match ( stuff ) and ) stuff ( with the same regex? How would this be a generalisation?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
      Well, technically the OP does say "surrounded", which could mean the boundaries are switched. Your usage of parens in the example is misleading, because parens are inherently related to internal grouping

      But I imagine (not tested) a simple extension of your original regexp could be in order.

      $str =~ s[(bar.+?qux)|(qux.+?bar)|(foo)][defined $3 ? '123' : (defined +($2) ? $2 : $1)]ge;
        Well, technically the OP does say "surrounded", ...

        Actually not.

        And the examples given do not indicate this possibility either.

        Perhaps more important is that "reversible bracketing" doesn't really make much sense. Consider

        foo < foo > foo < foo < foo > foo > foo < foo < foo > foo < foo > foo +> foo 123 |.....|.....| |.....| |.....| |.....|.....|.....| + 123 |.................| |............................. +|

        Can you conceive of an application where this would make sense?


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.