2010-08-09 75 views
2

我只是想知道如何應用preg_replace幾個規則而不執行它們在第一次運行。它有點複雜讓我根據一個例子來解釋。PHP preg_replace多個規則

輸入:

$string = 'The quick brown fox jumps over the lazy freaky dog'; 

規則:

  • 更換一個Øü(如果不是在一個單詞的開頭如果不是,則爲& E /後元音)
  • 更換ēü(如果不是在一個字&如果沒有開始前/後元音)
  • 更換EA (如果不是在一個單詞的開頭)
  • 更換整個單詞,即狐狸w^OLF(不應用上述規則)

輸出: 氏快速bruwn狼jimps超過THI luzy friky貓




我開始用類似的東西:(編輯感謝埃塞基耶爾Muns

$patterns = array(); 
$replacements = array(); 

$patterns[] = "/(?<!\b|[aeiou])[aio](?![aeiou])/"; 
$replacements[] = "u"; 

$patterns[] = "/(?<!\b|[aeiou])[eu](?![aeiou])/"; 
$replacements[] = "i"; 

$patterns[] = '/ea/'; 
$replacements[1] = 'i'; 

$patterns[] = '/dog/'; 
$replacements[0] = 'cat'; 

echo preg_replace($patterns, $replacements, $string); 

輸出:

Thi qiick briwn fix jimps ivir thi lizy friiky dig 



編輯:

正如你所看到的問題是,每一個規則被通過之前的規則覆蓋。

例 '狐狸':

  1. 規則:原來狐狸FUX
  2. 規則:原來FUX修復

是否有辦法如果角色是,則避免以下規則已經受到以前規則的影響?

這有道理嗎?

+0

'freaky'從哪裏來? Pfft。我想要一個正則表達式使它成爲正確的短語:P – 2010-08-10 00:00:52

回答

3

首先,你需要明確的替換條件,你的規則說'不是在一個詞的開頭,不在一個元音之前/之後',但你沒有在正則表達式中實現。您可以使用負面預測/ Lookbehind來做到這一點。例如:

$patterns[] = "/(?<!\b|[aeiou])[aio](?![aeiou])/"; 
$replacements[] = "u"; 

  1. (前一個單詞&如果不是一開始如果不是/元音後)替換,I,O用U

可與實現

此方法可用於實現前3條規則。

接下來的問題是,'狐狸'和'狗'將受到前3條規則的影響,所以你應該將更改版本更換爲'狼'和'貓'。所以對於狗=>貓:

$patterns[] = "/\bdug\b/"; 
$replacements[] = "cat"; 

注:因爲工作的preg_replace使用數組的方式,更好的做法是在$模式和$替換陣列不使用索引,因爲這些可能會產生誤導。像上面那樣使用[]運算符,所以你總是知道什麼是什麼。

第2部分:

Aha。我懂了。你需要讓替代品變得非常簡單。

你可以使用一個正則表達式來匹配第一種情況,即有問題的情況。然後,您可以使用preg_replace的一個有趣的奇怪功能:當您添加e修飾符時,替換字符串將被評估爲PHP代碼。結合捕獲組,它可以讓你決定是否輸出一個u或一個i根據你匹配。

$patterns[] = "/(?<!\b|[aeiou])([aeiou])(?![aeiou])/e"; 
$replacements[] = '("$1" == "e" || "$1" == "u")? "i":"u"'; 

*請注意元音匹配類中的/ e和()。

+0

感謝兄弟,這就像魅力。 :) 但請看看我上面編輯過的帖子。 – Mayko 2010-08-10 01:58:20

+0

呵呵另一件事,你需要確保你也在你的'/ ea /'中使用了lookbehind,因爲你說*不是在一個詞的開頭*。 – 2010-08-11 08:38:29

+0

你真了不起!非常感謝 – Mayko 2010-08-19 05:22:32