Simon
Simon

Reputation: 23151

preg_replace() function problem?

Look at this simple script please

$a = "test";
echo $b = preg_replace('/[^a](e)/',"<b>$1</b>",$a); // returns <b>e</b>st

I want to bold the "e" characters, when there is no "a" character before it.

Logically in $0 it must match "te", and in $1 - "e", but why it strips the first character in my example?

I can solve the task in another way, but i want to understand this behavior.

Thanks much

Upvotes: 2

Views: 312

Answers (4)

Blair McMillan
Blair McMillan

Reputation: 5349

@Coronatus gives you the code to fix the problem. The reason that you experience it is as follows:

In preg_replace('/[^a](e)/',"<b>$1</b>",$a) the '/[^a](e)/' part matches t and the e in test, but only stores the e (it's the only thing you have in brackets). So, when you do the replace, you are replacing the matched section (te) with your bolded stored value (e). This is why you are losing the first character.

The other option for code is:

preg_replace('/([^a])(e)/', '$1<b>$2</b>', $a);

Upvotes: 1

tchrist
tchrist

Reputation: 80423

Your error is that /[^a](e)/ does not say to match an "e" when there is no "a" right before it. Rather, it says match a non-"a" and an "e", and save the "e".

You need /(?<!a)(e)/. That says match an "e" when there is not an "a" right before it, which is what you said you wanted.

Upvotes: 2

Konrad Rudolph
Konrad Rudolph

Reputation: 545865

why it strips the first character in my example?

Because the match is two characters wide: the e, and the character before it (which is denoted by [^a]).

To change this, there are two ways. The easy is just to parenthesize your match:

echo $b = preg_replace('/([^a])(e)/',"$1<b>$2</b>",$a); // returns t<b>e</b>st

The second is to use a negative lookbehind:

echo $b = preg_replace('/(?<!a)(e)/',"<b>$1</b>",$a); // returns t<b>e</b>st

Upvotes: 3

Amy B
Amy B

Reputation: 17977

preg_replace('/([^a])e/', '$1<b>e</b>', $a);

Upvotes: 0

Related Questions