Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

i have been using the pattern:
s/(?<!\\)(\$[a-zA-Z0-9_]+)/whatever()/ge;
to replace all instances of non-escaped variable names in a source file with the output of whatever(). would there be any way to extend this pattern to NOT match $something[x] (so a scalar name followed by an array subscript, as that actually refers to an array, not a variable)..so basically look at ahead or something and ignore the pattern if its followed by a '['. thx.

Edit: chipmunk 2001-04-26

Replies are listed 'Best First'.
Re: problem with substitution regex
by MrNobo1024 (Hermit) on Apr 27, 2001 at 03:12 UTC
    You need to use a negative lookahead assertion. From perlre:
    (?!pattern) A zero-width negative lookahead assertion. For example /foo(?!bar)/ ma +tches any occurrence of ``foo'' that isn't followed by ``bar''.
    However, you can't just add (?!\[) because it will backtrack and match only part of the variable. So to ensure that it will only match the whole variable and not part, add a \b (word boundary): s/(?<!\\)(\$[a-zA-Z0-9_]+)\b(?!\[)/whatever()/ge;
Re: problem with substitution regex
by hdp (Beadle) on Apr 27, 2001 at 03:29 UTC
    MrNobo1024's answer is unfortunately incorrect. It will match and replace the $fo part of $foo[5], for example.

    You need to stop that by adding \w to the negative lookahead. s/(?<!\\)\$\w+(?![\[{\w])/whatever()/ge

    I've replaced [a-zA-Z0-9_] with the more compact and equivalent \w, and tested for $bar{baz} as well.

    This is still not perfect; it will munge $foo [5], which is valid (if rare) syntax. The easiest way to fix that is to use another regex, e.g. s/(\w) +([\[{])/$1$2/g

    hdp.

      I believe that is why MrNobo1024 had added the \b.
        After I posted my message. :)

        hdp.