我有一个单词和一个字符串数组,并希望在字符串中的单词中添加一个hashtag,它们在数组中匹配。我使用这个循环来查找和替换单词:
foreach($testArray as $tag){
$str = preg_replace("~\b".$tag."~i","#\$0",$str);
}
问题:假设我的数组中有“is”和“isolate”这个词。我将在输出中获得## 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
答案 0 :(得分: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~
如果您希望自己的方法有效,可以在\b
之后添加负面的背后隐藏:"~\b(?<!#)".$tag."~i","#\$0"
。 lookbehind将失败所有以#
开头的匹配。请参阅this PHP demo。
答案 1 :(得分: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;
这样,无论数组中的单词数是多少,您的字符串都只处理一次。