2010-11-10 117 views
2

看看这个简单的脚本,请preg_replace()函数的问题?

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

我想大胆的“E”字,在没有“一”之前,它的性格。

逻辑$0它必须匹配"te",并在$1 - "e",但为什么它剥离我的例子中的第一个字符?

我可以用另一种方式解决任务,但我想了解这种行为。

感谢很多

回答

3

为什么它去除在我的例子中第一个字符?

由于比赛是字符宽:所述e,和它之前的字符(其由[^a]表示)。

要改变这一点,有两种方法。最简单的就是要加上括号你的对手:

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

第二种是使用negative lookbehind

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

我发誓,你如何管理这么快写? – 2010-11-10 13:18:01

+0

[我们打字员第一,程序员第二。](http://www.codinghorror.com/blog/2008/11/we-are-typists-first-programmers-second.html) – 2010-11-10 13:20:58

+0

@Blair:练习。 ;-)但我实际上并不认为自己是一个快速的打字员。大部分上述帖子都是从问题中复制/粘贴的,我只需稍作调整并添加解释即可。 *然后*我去检查我是否已经正确记住了负面lookbehind的语法(我很少使用id),并在答案中添加了适当的链接。你的答案比我的原始文本多得多,而且你链接到第一个答案,所以你可能在*之后开始回答*。 – 2010-11-10 13:28:52

0

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

2

你的错误是/[^a](e)/说,当有匹配一个“e”在它之前没有“a”。相反,它表示匹配非“a”和“e”,并保存“e”。您需要/(?<!a)(e)/。这就是说,如果没有一个“a”,它就是一个“e”,这就是你说的你想要的。

1

@Coronatus为您提供解决问题的代码。您遇到它的原因如下:

preg_replace('/[^a](e)/',"<b>$1</b>",$a)'/[^a](e)/'部分匹配t和测试e,但只存储e(这是你在括号中有唯一)。因此,当您进行替换时,您将用粗体存储值(e)替换匹配的部分(te)。这就是你失去第一个角色的原因。

代码的另一种选择是:

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