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

how to build a regex to match a string with only an EVEN number of backslashes before it (or NO backslashes)? for instance, the string I want to match is a dollar sign followed by 1 or more digits.
 
to just match such a string, this would do: /\$\d+/
 
the backslash problem is throwing me, however, because I'd like to allow the end user to purposely escape said string with a backslash to avoid a match(\$1)...OR, if they need to include an actual backslash character before it, they'd need to *escape* the backlash while the string is still matched (\\$1)
 
# Some examples of what should and shouldnt match # should match '$1' "for the $1th time" # should not match "SELECT * FROM Product WHERE Price LIKE '\$2.59'" # should match '$10' "using fore- and back-slashes for emphasis: \\$10/" # should not match "escaping: \\\$6"
i'd much appreciate the help of monks wiser than myself!

Replies are listed 'Best First'.
Re: checking interpreted string for escapes versus literal backslashes?
by japhy (Canon) on Mar 27, 2006 at 23:46 UTC
    You'll want to preface each '\' in YOUR regex with (?<!\\)(?s:\\.)*). Try this code out:
    while (<DATA>) { chomp; print "matched '$1' in '$_'\n" if /(?<!\\)(?s:\\.)*(\$\d+)/; } __DATA__ for the $1th time SELECT * FROM Product WHERE Price LIKE '\$2.59' using fore- and back-slashes for emphasis: \\$10/ escaping: \\\$6

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: checking interpreted string for escapes versus literal backslashes?
by ambrus (Abbot) on Mar 28, 2006 at 11:43 UTC

    First, do a substitution like s/\\\\/\\x5c/g or something like that. Then, it's easy to match unescaped charaters, as you only have to check if there's a backslash behind it or not. This substitution can later be reversed if it's needed.

    (Using a double backslash as an escape sequece for backslashes is a very silly thing, even though C does that and everyone since blindly follows. There should have been an single-letter escape sequence like \B for backslash, to avoid all this exponential backlash growth thing.)

    Update 2008 aug 29: see also Replace only unescaped metachars.

    Update 2009 mar 31: see also Re^2: Game Nicknames to HTML.

      that's a good point, i think i'll borrow your \B idea and use it instead! perl should really include something along that line, because i cant remmber how many times i have to deal with "\\\\\$test" or a similar situation...

        Don't actually use \B though, as it's already a regexp meta-character. Better use some unused letter (though it's hard to find any).