Re: [MacPerl-AnyPerl] negative lookahead problem
[email protected] (Bart Lateur) Sun, 12 Aug 2001 15:13:41 +0200
| Newsgroups | perl.macperl.anyperl |
|---|---|
| Organization | MediaMind |
| Message-ID | <[email protected]> |
On Sat, 11 Aug 2001 15:26:16 +0200, allan wrote:
>ronald's script works out of the box. but again im not sure i understand
>why. for instance, what is the difference between | and || (precedence
>perhaps?) and why exactly are we using the /e modifier?
Well, Ronald explains the "/e" and "||' quite well, so let me focus on
that "|" part... take this as an example.
/(")|(.)/
Attempts at matching are tried from left to right. So, this regex will
attempt to match, for every character, a quote first, and *if that
fails*, any character but newline. If a quote is found, the first
subpattern matches, and the rest isn't even tried (even though it would
have matched). So in that case, $1 is set to what is matched, the quote,
and $2 is undef.
If there was another (normal) character, the first subpattern would have
failed, but the second would have matched. In that case, $1 would be
undef, and $2 would contain the matched character.
What if it was a newline? Well: both subpatterns would have failed, the
regex start-of-match pointer would have been increased, and the whole
circus begins again: first try for quote, next try for any normal
character... etc. until one of the two is found, or there are no more
characters to test.
A more complex example, is this:
/(".*?")|(\s+)/
This will attempt to match a quoted string, or whitespace. For a quoted
string, $1 will contain it, including the quotes, and $2 is undef; for a
whitespace character string, $2 will contain it, and $1 is undef. Note
that the quoted string can contain whitespace characters as well, so
this serves as a good method to distinguish whitespace between quotes
(in $1) and bare whitespace (in $2).
So, let's apply this:
s/(".*?")|(\s+)/$1 || ' '/ge;
If it matches a quoted string, $1 will set to it; since it contains at
least a quote character, it will be interpreted as true. So the RHS,
which is executed as perl code for every match, evaluation will stop at
the ||, the value of $1 is retained. Thus, quoted strings are preserved.
If instead, bare whitespace is found, $1 is undef (thus false), and
$1 || ' '
will evaluate to a space.
Net result: all whitespace is replaced by a single quote, except in
quoted strings.
Your problem neatly maps into this category.
--
Bart.