PHP令牌替换html实体

PHP令牌替换html实体,php,token,strtok,Php,Token,Strtok,如果在文本中找到某些单词/字符串,我想创建链接。我有一段php.bet中的代码可以做到这一点,但它也删除了中标记的开头和结尾。你能帮我解决这个问题吗 下面是一段代码: <?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>'; $r

如果在文本中找到某些单词/字符串,我想创建链接。我有一段php.bet中的代码可以做到这一点,但它也删除了
中标记的开头和结尾。你能帮我解决这个问题吗

下面是一段代码:

<?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);

不知道为什么会有这么大的结构,比如:

$str_out = preg_replace('/(' . preg_quote(implode('|', array_keys($replaces))) . ')/', $replaces[$1], $str_in);

会完成同样的事情。当然,使用正则表达式来处理HTML是一个困难的过程。您应该使用DOM和一些xpath来更可靠地执行此操作。

不确定为什么会有这么大的结构,例如:

$str_out = preg_replace('/(' . preg_quote(implode('|', array_keys($replaces))) . ')/', $replaces[$1], $str_in);

会完成同样的事情。当然,使用正则表达式来处理HTML是一个困难的过程。您应该使用DOM和一些xpath来更可靠地完成这项工作。

这对函数应该可以做您想要的而不会出现使用regex或
str\u replace解析HTML时出现的问题

函数过程($node,$replaceRules)
{
如果($node->hasChildNodes()){
$nodes=array();
foreach($node->childNodes作为$childNode){
$nodes[]=$childNode;
}
foreach($nodes作为$childNode的节点){
if($childNode instanceof DOMText){
$text=preg\u replace(
数组_键($replaceRules),
数组_值($replaceRules),
$childNode->wholeText);
$node->replaceChild(新的DOMText($text),$childNode);
}
否则{
进程($childNode,$replaceRules);
}
}
}
}
函数addLinks($str_in,$replaces)
{
$replaceRules=array();
foreach($替换为$k=>$v){
$k='/\b('.$k.)\b/i';
$v='';
$replaceRules[$k]=$v;
}
$doc=新文档;
$doc->loadHTML($str_-in);
流程($doc->documentElement,$replaceRules);
返回html_实体_解码($doc->saveHTML());
}
注意: 如果HTML的结构不好(如您的示例所示),则无需担心;然而,输出将是结构良好的

到期的信用:
递归
process()
函数完成了大部分实际工作,直接来自LukášLalinský的答案。
addLinks()
函数只是一个根据您的问题定制的用例。

这对函数应该可以做您想要的,而不会出现使用regex或
stru replace解析HTML时出现的问题

函数过程($node,$replaceRules)
{
如果($node->hasChildNodes()){
$nodes=array();
foreach($node->childNodes作为$childNode){
$nodes[]=$childNode;
}
foreach($nodes作为$childNode的节点){
if($childNode instanceof DOMText){
$text=preg\u replace(
数组_键($replaceRules),
数组_值($replaceRules),
$childNode->wholeText);
$node->replaceChild(新的DOMText($text),$childNode);
}
否则{
进程($childNode,$replaceRules);
}
}
}
}
函数addLinks($str_in,$replaces)
{
$replaceRules=array();
foreach($替换为$k=>$v){
$k='/\b('.$k.)\b/i';
$v='';
$replaceRules[$k]=$v;
}
$doc=新文档;
$doc->loadHTML($str_-in);
流程($doc->documentElement,$replaceRules);
返回html_实体_解码($doc->saveHTML());
}
注意: 如果HTML的结构不好(如您的示例所示),则无需担心;然而,输出将是结构良好的

到期的信用:
递归
process()
函数完成了大部分实际工作,直接来自LukášLalinský的答案。
addLinks()
函数只是一个根据您的问题量身定制的用例。

在这种情况下,$replaces[$1]是什么?我问这个是因为它抛出了一个错误。谢谢你的代码似乎不起作用。有人知道如何避免在这种情况下弄乱html实体吗?再次感谢!在这种情况下,$替换[$1]是什么?我问这个是因为它抛出了一个错误。谢谢你的代码似乎不起作用。有人知道如何避免在这种情况下弄乱html实体吗?再次感谢+1表示深思熟虑的问题,表明研究努力。+1表示深思熟虑的问题,表明研究努力。