Reputation: 557
Hi Stackoverflowianers,
please help me solving a simple regex problem:
Given strings (e.g.):
Hollg 21, Bergg 15, Rosenweg 81, Fernblickg 30
I want to replace all occurrences of a "g" followed by an empty space and a digit with the word "gasse" BUT NOT: if the regex finds the g
in weg 81
.
What I already tried: /[^(we)]g \d+/g
This regex works well but it takes not only the g
but also the letter before the g
(results: lg 21, gg 15, kg 30
). I only need the g 21
, the g 15
and the g 81
...
I'm sure it is very simple but I cant get it to work.
Upvotes: 2
Views: 137
Reputation: 1374
Try this expression instead:
<?php
$expression = '/(?<!we)g\s(\d+)/';
$input = 'Hollg 21, Bergg 15, Rosenweg 81, Fernblickg 30, weg 81, ceg 45';
$output = preg_replace($expression, 'gasse $1', $input);
//output = Holgasse 21, Bergasse 15, Rosenweg 81, Fernblicgasse 30, weg 81, cegasse 45
?>
Upvotes: 0
Reputation: 56809
To make sure that g
is not preceded by we
(which forms weg
), you should use zero-width negative look-behind (?<!pattern)
:
/(?<!we)g(?= \d)/
Zero-width negative look-behind will check that it is not possible to find we
right before the current position in the input string. Since it only checks without consuming text, it is zero-width.
I also modified the pattern to include a zero-width positive look-ahead (?=pattern)
that checks for presence of space and digit without consuming the text, i.e. it will not make the text matching the pattern inside the (?=pattern)
part of the match. This way, we don't have to capture the digit and put it back in the replacement string.
As a summary, the regex above will check that we
is not preceding g
, and g
is followed by space and a digit. (Well, there is no need to check for one or more - since the presence of one digit would satisfy the one or more condition anyway).
Then you can write your replacement code as:
$replaced = preg_replace('/(?<!we)g(?= \d)/', 'gasse', $inputString);
Upvotes: 3
Reputation: 4127
You were almost there, a minor modification to your regex and this should work for you
Rather than using a normal exclusion operation [^we]
you need to use a negative lookbehind to remove anything that matches the we
rather than just a g
following an e
. (See comments between me and nhahtdh)
<?php
$regex = '/(?<!we)g (\d+)/';
$input = 'Hollg 21, Bergg 15, Rosenweg 81, Fernblickg 30, weg 81';
$output = preg_replace($regex, 'gasse $1', $input);
//output = Holgasse 21, Bergasse 15, Rosenweg 81, Fernblicgasse 30, weg 81
You need to group the digit in your regex then use the reference to it in your replacement i.e the $1
Upvotes: 1