dongshao8471 2011-09-15 19:18
浏览 108
已采纳

PHP Token替换了html实体

I want to make certain words/strings like links if found in the text. I have a piece of code from php.bet which does that, but it also removes the beginning and end of tags from <a href="http://www.domain.com/index.php" title="Home">go to homepage</a>. Can you help solve this?

Here's the piece of code:

<?php

$str_in =   '<p>Hi there worm! You have a disease!</p><a href="http://www.domain.com/index.php" title="Home">go to homepage</a>';
$replaces=      array(
                'worm' => 'http://www.domain.com/index.php/worm.html',
                'disease' => 'http://www.domain.com/index.php/disease.html'
                );

function addLinks($str_in, $replaces)
{
  $str_out = '';
  $tok = strtok($str_in, '<>');
  $must_replace = (substr($str_in, 0, 1) !== '<');
  while ($tok !== false) {
    if ($must_replace) {
      foreach ($replaces as $tag => $href) {
        if (preg_match('/\b' . $tag . '\b/i', $tok)) {
          $tok = preg_replace(
                                '/\b(' . $tag . ')\b/i',
                                '<a title="' . $tag . '" href="' . $href . '">\1</a>',
                                $tok,
                                1);
          unset($replaces[$tag]);
        }
      }
    } else {
      $tok = "<$tok>";
    }
    $str_out .= $tok;
    $tok = strtok('<>');
    $must_replace = !$must_replace;
  }
  return $str_out;
}

echo addLinks($str_in, $replaces);

The result is:

Hi there worm! You have a disease!

a href="http://www.domain.com/index.php" title="Home"/a

The "worm" and "disease" words are transformed into links like desired, but the rest...

Thanks a lot!

  • 写回答

2条回答 默认 最新

  • duanlaiyin2356 2011-09-15 22:16
    关注

    This pair of functions should do what you want without the problems that come with parsing HTML with regex or str_replace.

    function process($node, $replaceRules)
    {
        if($node->hasChildNodes()) {
            $nodes = array();
            foreach ($node->childNodes as $childNode) {
                $nodes[] = $childNode;
            }
            foreach ($nodes as $childNode) {
                if ($childNode instanceof DOMText) {
                    $text = preg_replace(
                        array_keys($replaceRules),
                        array_values($replaceRules),
                        $childNode->wholeText);
                    $node->replaceChild(new DOMText($text),$childNode);
                }
                else {
                    process($childNode, $replaceRules);
                }
            }
        }
    }
    
    function addLinks($str_in, $replaces)
    {
        $replaceRules = array();    
        foreach($replaces as $k=>$v) {
            $k = '/\b(' . $k . ')\b/i';
            $v = '<a href="' . $v . '">$1</a>';
            $replaceRules[$k] = $v;
        }
    
        $doc = new DOMDocument;
        $doc->loadHTML($str_in);
        process($doc->documentElement, $replaceRules);
        return html_entity_decode($doc->saveHTML());
    }
    

    Note: No need to worry if the HTML is not well structured (as in your example); however, the output will be well structured.

    Credit where it’s due: The recursive process() function, which does most of the real work, comes direclty from Lukáš Lalinský’s answer to How to replace text in HTML. The addLinks() function is just a use case tailored to fit your question.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 如何绘制动力学系统的相图
  • ¥15 对接wps接口实现获取元数据
  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊
  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题
  • ¥15 企业资源规划ERP沙盘模拟