user148823
user148823

Reputation: 25

PHP RegEx - * is not greedy enough

I execute this:

$string = preg_replace('/^([^\|]*)(?!\|\|Read)/','$1||Read',"test||Read");
echo "$string<br>";
$string = preg_replace('/^([^\|]*)(?!.*Read)/','$1||Read',"test||Read");
echo "$string<br>";

and I get this:

tes||Readt||Read
test||Read

The idea is to add "||Read" after a string (not containing a pipe) if it doesn't exist. So why does the * in the first RegEx consume only "tes"?

The second RegEx works because the first * consumes "tes" and the second * in the assertion matches "t||" .

Upvotes: 0

Views: 128

Answers (1)

mario
mario

Reputation: 145482

You can make it more greedy or "possessive" by adding a + plus after the * quantifier:

 ([^\|]*+)

So your code becomes:

 $string = preg_replace('/^([^\|]*+)(?!\|\|Read)/','$1||Read',"test||Read");

Which for your test case doesn't leave the t over.

In your case, the ||Read should always occur at the line end? If so, you could also just use ^(.*?)$ for matching, and assert the line end instead (?<!Read)$.

Upvotes: 2

Related Questions