2017-01-30 24 views
1

我有一個單詞和一個字符串數組,並希望添加一個hashtag字符串中的單詞,他們有一個匹配的數組內。我用這個循環來查找和替換的話:preg替換會忽略非字母字符時檢測到的單詞

foreach($testArray as $tag){ 
    $str = preg_replace("~\b".$tag."~i","#\$0",$str); 
} 

問題:可以說我有詞「是」,並在我的數組「隔離」。我將在輸出處得到##隔離。這意味着「孤立」這個詞在「is」中找到一次,在「isolate」中找到一次。並且該模式忽略了「#isoldated」不再以「is」開頭並以「#」開頭的事實。

我帶來了一個例子,但這只是爲例 e和我不希望只是解決這一之一,但所有其他方法可行:

$str = "this is isolated is an example of this and that"; 
$testArray = array('is','isolated','somethingElse'); 

輸出將是:

this #is ##isolated #is an example of this and that 

回答

1

你可以建立一個正則表達式,在兩端用字邊界包圍一個交替組,並在一遍中替換所有匹配:

$str = "this is isolated is an example of this and that"; 
$testArray = array('is','isolated','somethingElse'); 
echo preg_replace('~\b(?:' . implode('|', $testArray) . ')\b~i', '#$0', $str); 
// => this #is #isolated #is an example of this and that 

查看PHP demo

正則表達式看起來像

~\b(?:is|isolated|somethingElse)\b~ 

看到它online demo

如果你想讓你的方法有效,你可以在\b"~\b(?<!#)".$tag."~i","#\$0"之後添加負面倒序。向後看將會在#之前的所有匹配失敗。見this PHP demo

1

一個辦法做到這一點是通過語言來分割你的字符串,並建立與您的原話的陣列中的關聯數組(避免使用的in_array):

$str = "this is isolated is an example of this and that"; 
$testArray = array('is','isolated','somethingElse'); 

$hash = array_flip(array_map('strtolower', $testArray)); 

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

for ($i=1; $i<count($parts); $i+=2) { 
    $low = strtolower($parts[$i]); 
    if (isset($hash[$low])) $parts[$i-1] .= '#'; 
} 

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

echo $result; 

這樣,你的字符串只處理一次,無論數組中的單詞數量如何。

相關問題