Ingmar Erdös
Ingmar Erdös

Reputation: 557

Very simple RegEx: Find occurrence but not in one case

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

Answers (3)

JonM
JonM

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

nhahtdh
nhahtdh

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

fullybaked
fullybaked

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

Related Questions