3

我有一个相当基本的情况,我有一个字符串数组,我想在一个字符串中找到所有匹配项,并在它们周围放置强标签。这是我到目前为止所拥有的:

$searchWords = array("test","this","s");

for($i=0;$i<sizeof($searchWords);$i++) {
    $searchWords[$i] = "/".preg_quote($searchWords[$i])."/i";
}

$label = "This is a test string.";

$result = preg_replace($searchWords, "<strong>$0</strong>", $label);

echo($result);

问题是 preg_replace 函数似乎将“s”搜索词与强标签匹配,因为它们被替换了。所以我结束了:

<strong>Thisstrong> 是一个 <strong>teststrong>。

当我真正想要的是:

<strong>这个</strong>我<strong>s</strong>是一个<strong>测试</strong>。

那么,你们能建议我哪里出错了吗?

任何帮助都非常感谢,我为此撕毁了我的头发,我必须接近。

4

2 回答 2

3

你不想做三个替换,而是一个:

$result = preg_replace("#" . implode($searchWords, "|") . "#", "<strong>$0</strong>", $label);

hakre 的编辑:这就像这个或那个或那个字符串。将进行第一场比赛。所以从最长的字符串开始,取最小的字符串作为最后一个。

二进制对此编辑的回答:见评论


完整版本:

<?php
$searchWords = array("t", "test", "this");
usort($searchWords, function ($a, $b) { return strlen($b) - strlen($a); });

foreach ($searchWords as &$word)
{
    $word = preg_quote($word);
}
unset($word);

$label = "This is a test string.";

$searchWords = implode($searchWords, "|");
$result = preg_replace("#{$searchWords}#i", "<strong>$0</strong>", $label);

echo($result);
于 2012-07-06T12:27:05.743 回答
0

确保不会发生这种情况的最简单方法是使用两个不会被替换的特殊“假标签”,然后替换它们,或者指定单词必须是完整的单词匹配并且在单词边界开始和结束.

  $result = preg_replace($searchWords, "<_^_>$0</_^_>", $label);
  $result = str_replace('_^_', 'strong', $result);

或者

  $searchWords[$i] = '/\b'.preg_quote($searchWords[$i]).'\b/i';

第二个更优雅(而且更快 - 我敢打赌也加快了搜索速度),但阻止您使用部分单词替换。

于 2012-07-06T12:22:53.330 回答