代码之家  ›  专栏  ›  技术社区  ›  fire

用某个类替换标记的内容

  •  1
  • fire  · 技术社区  · 15 年前

    我正在寻找合适的替换代码,它允许我替换任何具有特定类的HTML标记内的内容,例如。

    $class = "blah";
    $content = "new content";
    $html = '<div class="blah">hello world</div>';
    
    // code to replace, $html now looks like:
    // <div class="blah">new content</div>
    

    请牢记:

    1. 它不一定是一个分区,可能是 <h2 class="blah">
    2. 该类可以有多个类,但仍需要替换,例如 <div class="foo blah green">hello world</div>

    我认为正则表达式应该能够做到这一点,如果不能做到的话,我可以接受其他建议,比如使用DOM类(尽管我宁愿尽可能避免这样做,因为它必须与php4兼容)。

    3 回复  |  直到 15 年前
        1
  •  1
  •   Community CDub    8 年前

    Do not use regular expressions to parse HTML . 你可以使用内置的 DOMDocument 或者类似的 simple_html_dom :

    require_once("simple_html_dom.php");
    
    $class = "blah";
    $content = "new content";
    $html = '<div class="blah">hello world</div>';
    
    $doc = new simple_html_dom();
    $doc->load($html);
    
    foreach ( $doc->find("." . $class) as $node ) {
        $node->innertext = $content;
    }
    

    抱歉,我没有看到PHP4的要求。这里有一个使用上述标准domdocument的解决方案。

    function DOM_getElementByClassName($referenceNode, $className, $index=false) {
        $className = strtolower($className);
        $response  = array();
    
        foreach ( $referenceNode->getElementsByTagName("*") as $node ) {
            $nodeClass = strtolower($node->getAttribute("class"));
    
            if (
                    $nodeClass == $className || 
                    preg_match("/\b" . $className . "\b/", $nodeClass)
                ) {
                $response[] = $node;
            }
        }
    
        if ( $index !== false ) {
            return isset($response[$index]) ? $response[$index] : false;
        }
    
        return $response;
    }
    
    $doc = new DOMDocument();
    $doc->loadHTML($html);
    
    foreach ( DOM_getElementByClassName($doc, $class) as $node ) {
        $node->nodeValue = $content;
    }
    
    echo $doc->saveHTML();
    
        2
  •  -1
  •   b_i_d    15 年前

    如果您确定$html是有效的html代码,那么您可以使用html解析器,如果它是有效的xml代码,甚至可以使用xml解析器。

    但在regex中,快速而肮脏的方式是:

    $html = preg_replace('/(<[^>]+ class="[^>]*' . $class . '[^"]*"[^>]*>)[^<]+(<\/[^>]+>)/siU', '$1' . $content . '$2', $html);
    

    没有测试太多,但应该可以用。告诉我,如果你发现没有的话。

    编辑:添加了“和脏”…;)

    编辑2:regex的新版本:

    <?php
    
    $class = "blah";
    $content = "new content";
    $html = '<div class="blah test"><h1><span>hello</span> world</h1></div><div class="other">other content</div><h2 class="blah">remove this</h2>';
    
    $html = preg_replace('/<([\w]+)(\s[^>]*class="[^"]*' . $class . '[^"]*"[^>]*>).+(<\/\\1>)/siU', '<$1$2' . $content . '$3', $html);
    
    echo $html;
    
    ?>
    

    最后一个问题是,如果有一个类的名字中只有“blah”,比如“toomuchblahnow”。让我们看看如何解决这个问题。顺便问一句:很明显我喜欢和雷吉一起玩吗?;)

        3
  •  -2
  •   Brendan    15 年前

    不需要使用dom类,这可能是使用jquery最快完成的,正如khnle所说,或者可以使用preg_replace()函数。给我点时间,我可以给你写一个快速的正则表达式。

    但我建议您使用jquery之类的工具,这样您就可以快速地将页面提供给用户,并允许他们的计算机进行处理,而不是您的服务器。