"(?<=pattern)"
A zero-width positive look-behind assertion.
For example, "/(?<=\t)\w+/" matches a word that
follows a tab, without including the tab in $&.
Works only for fixed-width look-behind.
"(?<!pattern)"
A zero-width negative look-behind assertion.
For example "/(?<!bar)foo/" matches any occur-
rence of "foo" that does not follow "bar".
Works only for fixed-width look-behind.
Liz | [reply] |
Some advice to go along with what liz said. You don't need
to 'escape' percent signs and you posted the wrong operator
in your code that is broken. Here is that line of code,
slightly 'fixed':
$str =~ s/%q//g;
All you need to do here is add the zero-width negative
look-behind assertion and you are go to go. Think of this
as a 'helping you help yourself' solution. ;)
jeffa
L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)
| [reply] [d/l] |
A very minor note about your comment, you don't need to escape percent signs. You're right that it's not necessary, but I don't fault it.
In the perl5 incarnation, it's been very handy to remember that escaped alphanumerics are special and escaped non-alphanumerics are plain. Thus \s and \3 have special regex meanings while \% and \$ removes any regex meaning and gives literal characters. There are a scant few bits of punctuation which have no meaning in a regex, so I forgive any excess escaping as being more "obvious" or literate to the maintenance coder.
Perl6 turns regex syntax on its head in many ways (and allows interpolation of hashes), so it'll be interesting to see if there's still an easy mnemonic demarcation between special and literal.
-- [ e d @ h a l l e y . c c ]
| [reply] |
you don't need to confuse people with the extra syntax of look-ahead/behind....you just need to match exactly what you want "a non-percent sign character followed by a percent sign character followed by q", i.e. $str =~ s/[^%]%q//g;
| [reply] [d/l] |
That doesn't work if %q starts the line - try
/^%q|[^%]%q/
or use the negative look behind
/(?<!%)%q/ | [reply] [d/l] |
In addition to the problem leriksen pointed out, your suggestion deletes an extra character. In order to meet the OP's spec, it gets a bit uglier:
$str =~ s/^%q|([^%])%q/$1/g;
Basically, it would be less confusing to learn about zero-width assertions.
Granted, it does pose a bit of a challenge to "learn" the various zero-width and non-grouping forms. I haven't memorized them yet myself -- I just scan through the "perlre" man page every time I need to use one of those "(?whatever)" thingies. I actually don't mind that. I'm used to it from always having to do the same thing for a dozen different common C library calls -- I still do that, after "knowing" C for 15 years. | [reply] [d/l] |
But what if you have %%%q? Should it match the
%q or not? If it should, you might want to use:
s/(%.)/$1 eq "%q" ? "" : $1/eg;
Abigail | [reply] [d/l] |