【问题标题】:Acceptable use of Regex in HTML parsing?在 HTML 解析中是否可以使用 Regex?
【发布时间】:2011-03-09 22:47:15
【问题描述】:

关于何时以及是否适合使用正则表达式来解析 html 存在很多争论。

出现的一个常见问题是从 html 解析链接,我的问题是,如果您要查找的只是 HTML 块中 <a> 标记的 href 值,那么使用正则表达式是否合适?在这种情况下,您不关心结束标签,并且您正在寻找一个非常具体的结构。

使用完整的 html 解析器似乎有点过头了。虽然我看到问题和答案表明使用正则表达式来解析 URL,虽然在很大程度上安全并不完美,但结构化 <a> 标签的额外限制似乎提供了一个上下文,一个应该能够在不破坏的情况下达到 100% 的准确性出汗。

想法?

【问题讨论】:

    标签: html regex


    【解决方案1】:

    考虑一下这个有效 html:

    <!DOCTYPE html>
    <title>Test Case</title>
    <p>
    <!-- <a href="url1"> -->
    <span class="><a href='url2'>"></span>
    <a href='my">url<'>click</a>
    </p>
    

    要提取的 url 列表是什么?解析器只会说一个值为my"&gt;url&lt; 的url。你的正则表达式会吗?

    【讨论】:

    • 您甚至不必对 CDATA 及其同类产品感到讨厌,就可以提出一个在 HTML 上不使用正则表达式的令人信服的理由。
    • html 评论是一个很好的例子,但我认为你的古怪课程是无效的 html。
    • @Endophage - 如果您怀疑我的有效性声明,可以在这里轻松查看:validator.w3.org/#validate_by_input。只需复制并粘贴我的示例,然后单击“检查”按钮。
    • @Alohci...有趣...我之前在生成的 html 中遇到过问题,最终在属性值中有
    【解决方案2】:

    我是那些认为在这种情况下使用正则表达式是个坏主意的人之一。

    即使您只想匹配来自&lt;a&gt; 标记的href 属性,您的正则表达式仍将贯穿整个html 文档,这会使任何基于正则表达式的解决方案变得混乱、不安全和臃肿。

    另外,使用 XML 解析器匹配标签中的 href 属性几乎是多余的。

    至少 2 年以来,我每周都在解析 html 页面。起初,我使用的是完整的正则表达式解决方案,我认为它比使用 HTML 解析器更容易和简单。

    但由于很多原因,我不得不多次返回我的代码:

    • 源代码已更改
    • 其中一个源页面的 html 已损坏,我没有对其进行测试
    • 我没有对源代码的每一页都尝试我的代码,只是发现其中一些不起作用。
    • ...

    我发现修复长的正则表达式模式并不是最有趣的事情,你必须一遍又一遍地考虑它。

    从现在开始我通常是:

    • 使用tidy清理html源代码。
    • 使用DOM + Xpath 实际解析页面并提取我想要的部分。
    • 仅在小的纯文本部分使用正则表达式(例如节点的修剪后的textContent

    代码更加健壮,我不必花 2 小时在一个冗长的正则表达式模式上来找出它为什么不适用于 1% 的源,它只是感觉合适。

    现在,即使在我不关心结束标签并且我有一个非常具体的结构的情况下,我仍在使用基于 DOM 的解决方案,以不断提高我使用 DOM 库的技能并生成更好的代码。

    我不喜欢在这里看到有人在每个带有 html+regex 标记的问题上只评论“不要在 html 上使用 regex”,而没有提供示例代码或其他内容。

    这是一个匹配 PHP 中链接的 href 属性的示例,只是为了表明使用 HTML 解析器来处理这些常见任务一点也不夸张。

    $dom = new DOMDocument(); 
    $dom->loadHTML($html); 
    
    // loop on every links
    foreach($dom->getElementsByTagName('a') as $link) { 
        // get href attribute
        $href = $link->getAttribute('href');
        // do whatever you want with them...
    }
    

    我希望这会有所帮助。

    【讨论】:

    • 感谢您提供的所有信息。我试过使用 PHP 的 DOM 解析器(我没有选择从 PHP 更改),对于我需要解析然后输出的情况,它太慢了......它在 4 秒的区域内增加了页面加载的时间基于正则表达式的解决方案。
    【解决方案3】:

    我提出了这个:

    <a.*?href=["'](?<url>.*?)["'].*?>(?<name>.*?)</a>
    

    在这个thread

    最终它可能会因name 中的内容而失败。

    猜你喜欢
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    • 2017-04-28
    相关资源
    最近更新 更多