2016-10-15 18 views
4

我是PHP新手,特別是正則表達式。 我的目標是自動豐富textes,提示數組中列出的「關鍵字」。從數組中替換(添加)字區分大小寫

到目前爲止,我來了。

$pattern = array("/\bexplanations\b/i", 
      "/\btarget\b/i", 
      "/\bhints\b/i", 
      "/\bhint\b/i", 
); 

$replacement = array("explanations <i>(Erklärungen)</i>", 
      "target <i>Ziel</i>", 
      "hints <i>Hinsweise</i>", 
      "hint <i>Hinweis</i>", 
); 

$string = "Target is to add some explanations (hints) from an array to 
this text. I am thankful for every hint."; 

echo preg_replace($pattern, $replacement, $string); 

回報:

target <i>Ziel</i> is to add some explanations <i>(Erklärungen)</i> (hints <i>Hinsweise</i>) from an array to this text. I am thankful for every hint <i>Hinweis</i> 

1)一般來說,我不知道是否有更優雅的解決方案(最終無需更換原來的字)? 在稍後的狀態下,陣列將包含超過1000個項目......並來自mariadb。

2)如何獲得,「目標」一詞是否實現了區分大小寫的治療? (沒有重複我的數組的長度)。

對不起,我的英語和很多預先感謝。

+0

在正則表達式模式中用圓括號括起搜索詞,並在替換中使用退格。 –

回答

1

在正則表達式模式中用圓括號括起搜索詞並在替換中使用回退。

看到這個PHP demo

$pattern = array("/\b(explanations)\b/i", "/\b(target)\b/i", "/\b(hints)\b/i", "/\b(hint)\b/i",); 
$replacement = array('$1 <i>(Erklärungen)</i>', '$1 <i>Ziel</i>', '$1 <i>Hinsweise</i>', '$1 <i>Hinweis</i>',); 
$string = "Target is to add some explanations (hints) from an array to this text. I am thankful for every hint."; 
echo preg_replace($pattern, $replacement, $string); 

這樣,你會在文本中使用的實際情況找到的話更換。

注意事項,以確保圖案去的順序依次具有較長的模式之前,短的(第一Targets,然後Target等)

+0

哇。非常感謝。這完全解決了我的問題,併爲我在這個主題領域進一步研究和研究提供了正確的方向。儘管正則表達式似乎很難學,但它們確實很強大。再次感謝您的演示。 –

+0

Finnaly完成。關於我的NewB狀態,在你回答的時候我不被允許......。 –

2

未來是非常重要的如果項目,以提高你的數組的大小如果文本可能有點長,處理所有文本(每個文本一次)不是可靠的方法。而且,對於一個龐大的陣列來說,用所有單詞建立一個巨大的交替是不可靠的。 但是,如果你存儲在一個關聯數組的所有翻譯和分裂的字邊界的文字,你可以做一個合格:

// Translation array with all keys lowercase 
$trans = [ 'explanations' => 'Erklärungen', 
      'target' => 'Ziel', 
      'hints' => 'Hinsweise', 
      'hint' => 'Hinweis' 
]; 

$parts = preg_split('~\b~', $text); 

$partsLength = count($parts); 

// All words are in the odd indexes 
for ($i=1; $i<$partsLength; $i+=2) { 
    $lcWord = strtolower($parts[$i]); 

    if (isset($trans[$lcWord])) 
     $parts[$i] .= ' <i>(' . $trans[$lcWord] . ')</i>'; 
} 

$result = implode('', $parts); 

其實這裏的限制是不能使用的密鑰包含一個單詞邊界(如果你想翻譯一個完整的表達式,例如幾個單詞),但是如果你想處理這種情況,你可以用preg_match_all代替preg_split,並建立一個模式來測試這些特殊情況,如:

preg_match_all('~mushroom pie\b|\w+|\W*~iS', $text, $m); 

$parts = &$m[0]; 
$partsLength = count($parts); 

$i = 1^preg_match('~^\w~', $parts[0]); 

for (; $i<$partsLength; $i+=2) { 

... 

(如果您有人其他策略是可能的。)

+0

非常感謝。作爲noob我需要幾個小時才能逐行通過。經過測試學習目的後,我仍然對這種穩定性如何工作感到欣慰,特別是當我使用雙空白等輸入時儘管我目前的技能不夠成熟,無法完全解決性能問題,但我的進一步研究成爲了一個重要的更具體的方向。 –

+0

@FriedrichSiever:性能問題很簡單,對模式數組使用'preg_replace'(或'str_replace')涉及一個隱式循環,主題字符串爲數組中的每個項目完全處理(簡而言之,如果您有1000個字,該字符串將被解析1000次,並且每次替換後該字符串將會增長)。如果你使用我的解決方案,字符串只被解析一次以構建零件數組,那麼如果在替換數組中有一個關鍵字(構建替換數組,那麼你只需要測試一半部分(單詞)),避免使用'in_array') –

+0

@FriedrichSiever:其他問題,考慮文本:''小孩在玩。''和數組'''child'=>'Kind','kind'=>'藝術'] ',用'preg_replace'或'str_replace'方法,你得到:''一個小孩(種類(藝術)正在播放。我希望你沒有一個帶有「胖」字的文字。 –

相關問題