代码之家  ›  专栏  ›  技术社区  ›  Patrick Desjardins

如何使用regex通过类删除整个HTML标记(及其内容)?

  •  7
  • Patrick Desjardins  · 技术社区  · 17 年前

    我对雷杰克斯不是很在行,但我正在学习。

    我想按类名删除一些HTML标记。这就是我目前为止所拥有的:

    <div class="footer".*?>(.*?)</div>
    

    第一个?*?因为它可能包含其他属性,第二个原因是它可能包含其他HTML内容。

    我做错什么了?我试了很多套但没有成功。

    更新

    在DIV中,它可以包含多行,我正在使用PerlRegex。

    8 回复  |  直到 17 年前
        1
  •  13
  •   Chris Marasti-Georg Scott Weinstein    17 年前

    您还需要在DIV标记中的类之前考虑其他内容。

    <div[^>]*class="footer"[^>]*>(.*?)</div>
    

    另外,不区分大小写。您可能需要转义引号或结束标记中的斜线。你在做这个的背景是什么?

    还要注意,根据输入的不同,使用正则表达式进行HTML解析可能非常麻烦。下面的答案提出了一个很好的观点——假设您的结构如下:

    <div>
        <div class="footer">
            <div>Hi!</div>
        </div>
    </div>
    

    尝试为它构建一个regex会带来灾难。您最好的选择是将文档加载到一个DOM中,并对此执行操作。

    应紧密映射到xml::dom的伪代码:

    document = //load document
    divs = document.getElementsByTagName("div");
    for(div in divs) {
        if(div.getAttributes["class"] == "footer") {
            parent = div.getParent();
            for(child in div.getChildren()) {
                // filter attribute types?
                parent.insertBefore(div, child);
            }
            parent.removeChild(div);
        }
    }
    


    这是一个Perl库, HTML::DOM 和另一个, XML::DOM
    .NET具有用于处理DOM分析的内置库。
        2
  •  17
  •   Yanick    17 年前

    正如其他人所说,HTML是众所周知的难以处理使用regex的问题,而DOM方法可能更好。例如。:

    use HTML::TreeBuilder::XPath;
    
    my $tree = HTML::TreeBuilder::XPath->new;
    $tree->parse_file( 'yourdocument.html' );
    
    for my $node ( $tree->findnodes( '//*[@class="footer"]' ) ) {
        $node->replace_with_content;   # delete element, but not the children
    }
    
    print $tree->as_HTML;
    
        3
  •  1
  •   moritz    17 年前

    在Perl中,您需要 /s 修饰符,否则点与换行符不匹配。

    也就是说,使用适当的HTML或XML解析器删除HTML文件中不需要的部分更为合适。

        4
  •  0
  •   Hamish Downer JKP    17 年前

    部分取决于您使用的确切regex引擎-哪种语言等,但有一种可能是您需要转义引号和/或正斜杠。你可能还想让它不区分大小写。

    <div class=\"footer\".*?>(.*?)<\/div>
    

    否则,请说出你使用的语言/平台——.NET、Java、Perl…

        5
  •  0
  •   Daniel Spiewak    17 年前

    试试这个:

    <([^\s]+).*?class="footer".*?>([.\n]*?)</([^\s]+)>
    

    最大的问题是嵌套标签。例如:

    <div class="footer"><b></b></div>
    

    给定的regexp将通过 </b> 离开 </div> 悬在末端。您必须假定要查找的标记没有嵌套元素,或者需要使用某种类型的解析器(从HTML到DOM)和xpath查询来删除整个子树。

        6
  •  0
  •   Graeme Perrow    17 年前

    由于正则表达式的贪婪性,这将是很棘手的,(请注意,我的示例 可以 针对Perl,但我知道贪婪是Res.)的一个普遍问题。 .*? 将尽可能匹配 </div> ,因此,如果您有以下内容:

    <div class="SomethingElse"><div class="footer"> stuff </div></div>

    表达式将匹配:

    <div class="footer"> stuff </div></div>

    这不太可能是你想要的。

        7
  •  0
  •   Michelle    17 年前
    <div[^>]*class="footer"[^>]*>(.*?)</div>
    

    为我工作,但需要在特殊字符之前使用反斜杠

    <div[^>]*class=\"footer\"[^>]*>(.*?)<\/div>
    
        8
  •  -3
  •   Nick    17 年前

    为什么不 <div class="footer".*?</div> 我也不是一个regex专家,但我认为您不需要为open-div标记指定最后一个括号。