preg replace会在检测到单词

时间:2017-01-30 09:07:52

标签: php regex preg-replace

我有一个单词和一个字符串数组,并希望在字符串中的单词中添加一个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

2 个答案:

答案 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~

online demo

如果您希望自己的方法有效,可以在\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;

这样,无论数组中的单词数是多少,您的字符串都只处理一次。