2013-10-11 193 views
20

我使用的preg_replace在PHP中找到並替換字符串中的特定單詞,像這樣:PHP的preg_replace:不區分大小寫匹配區分大小寫更換

$subject = "Apple apple"; 
print preg_replace('/\bapple\b/i', 'pear', $subject); 

其中給出結果「梨」。

我希望能夠做到的是以不區分大小寫的方式匹配一個單詞,但尊重它是被替換的情況 - 給出結果'梨梨'。

下工作,但似乎有點長篇大論對我說:

$pattern = array('/Apple\b/', '/apple\b/'); 
$replacement = array('Pear', 'pear'); 
$subject = "Apple apple"; 
print preg_replace($pattern, $replacement, $subject); 

有沒有更好的方式來做到這一點?

更新:進一步對下面提出的優秀查詢,爲了這個任務的目的,我只想尊重'標題案例' - 因此一個詞的第一個字母是否是大寫。

+0

中所見。唯一不清楚的是:如果您的替換項和原始單詞具有不同的長度和原始單詞,該怎麼辦?大寫字母在更高的位置?即「'applE''和'pear''然後呢? –

+0

優秀點。爲了這個特定任務的目的,我只想尊重'標題大小寫'(因此第一個字母是否是大寫字母)。非常感謝您提供進一步的澄清。 – colin

回答

7

我心目中的共同情況下,該實施:

$data = 'this is appLe and ApPle'; 
$search = 'apple'; 
$replace = 'pear'; 

$data = preg_replace_callback('/\b'.$search.'\b/i', function($matches) use ($replace) 
{ 
    $i=0; 
    return join('', array_map(function($char) use ($matches, &$i) 
    { 
     return ctype_lower($matches[0][$i++])?strtolower($char):strtoupper($char); 
    }, str_split($replace))); 
}, $data); 

//var_dump($data); //"this is peaR and PeAr" 

- 它的更復雜,當然,但適合任何位置原始請求。如果你正在尋找只有第一個字母,這可能是矯枉過正(見@喬恩的回答則)

10

您可以用preg_replace_callback做到這一點,但是這更是長篇大論:

$replacer = function($matches) { 
    return ctype_lower($matches[0][0]) ? 'pear' : 'Pear'; 
}; 

print preg_replace_callback('/\bapple\b/i', $replacer, $subject); 

此代碼只是看起來在比賽的第一個字符,以確定如何處理取代的資本;你可以調整代碼來做更多的事情。

+0

我試過了你的代碼,但是我得到了Catchable致命錯誤:類Closure的對象無法轉換爲字符串... – c3cris

+0

@ c3cris我在上面的代碼片段中錯誤地寫了'preg_replace'而不是'preg_replace_callback',即使第一行提到的是正確的。固定。 – Jon

+0

這是一個更加優雅的解決方案。一眼就能理解得更加簡短。 +1 – JustCarty

3

這是我使用的解決方案:

$result = preg_replace("/\b(foo)\b/i", "<strong>$1</strong>", $original); 

在我,我可以」最好的詞我會試着解釋爲什麼這會起作用:用()包裝您的搜索字詞意味着我想稍後訪問此值。因爲它是正則表達式中的第一個項目,所以可以通過$1進行訪問,如替代參數

+0

然後看看它和預期答案的區別。對所有工程師來說,提醒一下「保持簡單」。 – Meiji