in reply to "Not containing something" in substitution

perldoc -q balanced finds Can I use Perl regular expressions to match balanced text? in perlfaq6. That answers your question precisely. It also refers you to perlre, which says

(??{ code })

WARNING: This extended regular expression feature is considered highly experimental, and may be changed or deleted without notice. A simplified version of the syntax may be introduced for commonly used idioms.

This is a "postponed" regular subexpression. The code is evaluated at run time, at the moment this subexpression may match. The result of evaluation is considered as a regular expression and matched as if it were inserted instead of this construct.

The code is not interpolated. As before, the rules to determine where the code ends are currently somewhat convoluted.

The following pattern matches a parenthesized group:

$re = qr{ \( (?: (?> [^()]+ ) # Non-parens without backtracking | (??{ $re }) # Group with matching parens )* \) }x;

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: Re: "Not containing something" in substitution
by CombatSquirrel (Hermit) on Aug 28, 2003 at 12:39 UTC
    Neat RegEx. Note that this does not solve strat's problem with this RegEx, as he is looking for a substitution and not a matching, and as it is nested it will be really hard to do a substitution with it. This can be understood as a challenge ;-).
    Still, I modified the RegEx a bit to work with strat's problem, at least for matching
    use re 'eval'; $begin = '[xyz]'; $end = '[/xyz]'; $string = '[xyz]level 1.1 [xyz]level 2.1[/xyz] rest of 1.1 [/xyz]'; $re = qr{ \Q$begin\E (?: (?> (?:(?!=\Q$begin\E|\Q$end\E).)+ ) | (??{ $re }) )* \Q$end\E }x; print 'Yeah!' if $string =~ $re;
    I just have too much free time ;-)
    Cheers, CombatSquirrel.
    Entropy is the tendency of everything going to hell.
      Why?
      use strict; use warnings; use re 'eval'; my $begin = qr!\Q[xyz]!; my $end = qr!\Q[/xyz]!; my @match; my $re; $re = qr{ $begin ( (?: (?> (?:(?!=$begin|$end).)+ ) | (??{ $re }) )* ) $end }x; $_ = '[xyz][xyz]level 1.1 [xyz]level 2.1[/xyz] rest of 1.1 [/xyz]'; 1 while s!$re!<xyz>$1</xyz>!; print; __END__ <xyz><xyz>level 1.1 [xyz]level 2.1</xyz> rest of 1.1 </xyz>

      Makeshifts last the longest.

Re: Re: "Not containing something" in substitution
by BrowserUk (Patriarch) on Aug 28, 2003 at 19:14 UTC

    Am I wrong in thinking that this will only handle two levels of nesting?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.

      Yes. The (??{ }) construct is evaluated at match time if and only when the engine reaches that point.

      Makeshifts last the longest.

        Right. I was thinking of the (?>..) example that only matches upto two deep.

        m{ \( ( [^()]+ # x+ | \( [^()]* \) )+ \) }x

        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
        If I understand your problem, I can solve it! Of course, the same can be said for you.