2010-11-10 119 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);