Krab Krab - 6 months ago 8
Perl Question

How do I replace all occurrences of certain characters with their predecessors?

$s = "bla..bla";
$s =~ s/([^%])\./$1/g;


I think it should replace all occurrences of
.
that is not after
%
with the character that is before
.
.

But
$s
is then:
bla.bla
, but
it should be
blabla
. Where is the problem? I know I can use quantifiers, but I need do it this way.

Answer

When a global regular expression is searching a string it will not find overlapping matches.

The first match in your string will be a., which is replaced with a. When the regex engine resumes searching it starts at the next . so it sees .bla as the rest of the string, and your regex requires a character to match before the . so it cannot match again.

Instead, use a negative lookbehind to perform the assertion that the previous character is not %:

$s =~ s/(?<!%)\.//g;

Note that if you use a positive lookbehind like (?<=[^%]), you will not replace the . if it is the first character in the string.