preg_replace()函数问题?

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

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

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

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.

@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);