in reply to Replacement Regex

$find = '$a'; $find = quotemeta $find; $replace = '$b'; $str = '($a $a hi) $a (($a) $a'; $str =~ s[(\([^)]*$find)|$find] [$1 ? $1 : $replace ]eg; print $str;

We find either (...$find or $find. When we find an opening parenthesis we move as far as we can to get $a (without passing a closing parenth) so that we do not substitute the second $a in the first parenth in my example. We then see if we have captured something in $1. If so we substitute what we found back in, effectively leaving the string unchanged. If not we do the replacement. You have not indicated how you want to handle mismatched or nested parentheses. This will not handle nesting 'correctly'. If you need to handle nesting you would do well to look at Text::Balanced

cheers

tachyon

s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Replies are listed 'Best First'.
Re: Re: Replacement Regex
by danger (Priest) on Mar 20, 2002 at 19:06 UTC

    This one will handle nested parens:

    #!/usr/bin/perl -w use strict; $_ = '$a ($a (hi) $a) $a (()$a)'; my $re; $re = qr/(?:[^\(\)]*|\((??{$re})\))+/; s/(\($re\))|\$a/$1?$1:'$b'/eg; print;

    Update: should've referred to perlre manpage instead of relying on memory, the version there makes it somewhat nicer:

    my $re; $re = qr/\((?:(?>[^()]*)|(??{$re}))*\)/; s/($re)|\$a/$1?$1:'$b'/eg;

    Update: It appears to broken in 5.6.0 (gives output as tachyon shows below), but it works for me with 5.6.1.

      <BEGIN_TEMPT_FATE>This one will handle nested parens:</END_TEMPT_FATE>

      $_ = '(($a $a hi) $a ($a) $a)'; my $re; $re = qr/\((?:(?>[^()]*)|(??{$re}))*\)/; s/($re)|\$a/$1?$1:'$b'/eg; print; __DATA__ (($a $a hi) $b ($a) $b)

      Oops!

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

        $_ = '(($a $a hi) $a ($a) $a) $a ($a) $a '; my $re; ($re=$_) =~ s/((\()|(\))|.)/${['(','']}[!$2]\Q$1\E${[')','']}[!$3]/gs; $re = join'|',map{quotemeta}eval{/$re/}; die $@ if $@ =~ /unmatched/; s/($re)|\$a/$1?$1:'$b'/eg;
Re: Re: Replacement Regex
by Anonymous Monk on Mar 20, 2002 at 19:40 UTC
    I've already parsed the line so that any incorrect syntax (i.e. an open paren without a closing paren) is an error and will not be an issue. Also, ((dfs) is ok, the second ( is just treated as an ordinary character within the outer parentheses.. that is to say, there is no nesting. That said.. thanks very much for your help!