【问题标题】:Replacing words with tag links in PHP用PHP中的标签链接替换单词
【发布时间】:2011-03-31 07:05:52
【问题描述】:

我有一个文本 ($text) 和一个单词数组 ($tags)。文本中的这些词应该替换为指向其他页面的链接,这样它们就不会破坏文本中的现有链接。在 CakePHP 中,TextHelper 中有一个方法可以执行此操作,但它已损坏,并且会破坏文本中现有的 HTML 链接。该方法假设如下:

$text=Text->highlight($text,$tags,'<a href="/tags/\1">\1</a>',1);

下面是 CakePHP TextHelper 中已有的代码:

function highlight($text, $phrase, $highlighter = '<span class="highlight">\1</span>', $considerHtml = false) {
  if (empty($phrase)) {
    return $text;
  }

  if (is_array($phrase)) {
    $replace = array();
    $with = array();

    foreach ($phrase as $key => $value) {
      $key = $value;
      $value = $highlighter;
      $key = '(' . $key . ')';
      if ($considerHtml) {
        $key = '(?![^<]+>)' . $key . '(?![^<]+>)';
      }
      $replace[] = '|' . $key . '|ix';
      $with[] = empty($value) ? $highlighter : $value;
    }
    return preg_replace($replace, $with, $text);
  } else {
    $phrase = '(' . $phrase . ')';
    if ($considerHtml) {
      $phrase = '(?![^<]+>)' . $phrase . '(?![^<]+>)';
    }

    return preg_replace('|'.$phrase.'|i', $highlighter, $text);
  }
}

【问题讨论】:

    标签: php regex cakephp tags


    【解决方案1】:

    您可以在此处查看(并运行)此算法:

    http://www.exorithm.com/algorithm/view/highlight

    通过一些更改,它可以变得更好更简单,但它仍然不完美。虽然效率较低,但我会推荐 Ben Doom 的一种解决方案。

    【讨论】:

      【解决方案2】:

      替换 HTML 中的文本与替换纯文本有着根本的不同。要确定文本是否是 HTML 标记的一部分,您需要查找所有标记以便不考虑它们。正则表达式并不是真正的工具。

      我会尝试以下解决方案之一:

      • 找到所有单词的位置。从最后到第一个工作,确定每个是否都是标签的一部分。如果没有,请添加锚点。
      • 将字符串拆分成块。每个块要么是标签,要么是纯文本。在纯文本块上运行替换,然后重新组装。

      我认为第一个可能更高效一些,但更容易出现程序员错误,所以我将它留给你。

      如果你想知道我为什么不直接解决这个问题,请查看网站上关于正则表达式和 HTML 的所有问题,以及正则表达式如何不是解析器。

      【讨论】:

        【解决方案3】:

        这段代码工作得很好。您可能需要做的是检查 &lt;span class="highlight"&gt; 的 CSS 并确保将其设置为某种颜色,以便您区分它是高亮的。

        .highlight { background-color: #FFE900; }
        

        【讨论】:

        • 我不是在问突出显示。请阅读问题。
        • 你会提供样品$text 看看吗?当我测试它时,代码工作得很好。我会说您要替换的$tags 可能存在于已定义的&lt;a href 标记中。这段代码不是为了换掉href,而是将它添加到$tags定义的单词中。
        【解决方案4】:

        Amorphous - 我注意到 Gert 编辑了您的帖子。这两个代码片段与您发布的完全相同吗?

        因此,即使原始代码是为突出显示而设计的,我了解您正在尝试将其重新用于生成链接 - 它应该并且确实可以正常工作(已发布测试)。

        但是在第一个代码片段中转义可能是一个问题。

        $text=Text->highlight($text,$tags,'<a href="/tags/\1">\1</a>',1);
        

        工作正常...但是如果您使用语音标记而不是引号,则反斜杠会作为转义符号消失 - 您需要将它们转义。如果不这样做,您将获得 %01 个链接。

        用语音标记的正确方法是:

        $text=Text->highlight($text,$tags,"<a href=\"/tags/\\1\">\\1</a>",1);
        

        (注意使用 \1 而不是 \1)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-17
          • 2010-09-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-19
          相关资源
          最近更新 更多