2017-01-30 22 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; 

这样,你的字符串只处理一次,无论数组中的单词数量如何。

相关问题