尝试在 C# 中使用正则表达式获取整个 <div>

Posted

技术标签:

【中文标题】尝试在 C# 中使用正则表达式获取整个 <div>【英文标题】:Trying to get a whole <div> with regex in c# 【发布时间】:2013-05-02 16:37:36 【问题描述】:

我正在尝试在 c# 中抓取整个 div 元素...

我试过div class="txt-block"\s*(.+?)(\r\n?|\n)\s*" 但它并没有完全刮掉它:( 有任何想法吗? 这是 div.. THX!

    <div class="txt-block" itemprop="creator" itemscope itemtype="http://schema.org/Person"> 
    <h4 class="inline">Writers:</h4>
    <a href="/name/nm1318843/?ref_=tt_ov_wr" itemprop='url'><span class="itemprop"    itemprop="name">Mark Fergus</span></a>               (screenplay), 
    <a href="/name/nm1319757/?ref_=tt_ov_wr" itemprop='url'><span class="itemprop"         
    itemprop="name">Hawk Ostby</span></a>               (screenplay), <a href="fullcredits?ref_=tt_ov_wr#writers" >6 more credits</a>&nbsp;&raquo;
</div> 

【问题讨论】:

您真的需要阅读this 才能理解为什么 RexEx 和 html 解析不能结合使用。 改用HTML Parser。 您无法使用正则表达式解析 HTML。大多数语言都有 HTML 解析器,在线查找或 HTML 解析器。如果你想自己做,你需要做更多的工作。 【参考方案1】:

为什么会有这么多反对票?因为您不会使用正则表达式解析 HTML,所以不允许他?太狭隘了。

我发现 htmlagilitypack 无法正确解析格式错误的 html 文档,或者无法解析大量捕获的串联或嵌套 HTML 文档的情况占很大比例。或者任何形式的 XPath 都不起作用,因为 HTML 文档是动态创建的,不一致,并且不一定包含标识属性。当一个非常简单的正则表达式无论如何都可以更可靠时,为什么要导入额外的包含并解决草率的标记?

如果您有一个大型项目,而您的项目中的一个方法只需要提取输入 HTML 文档的 DIV 的内容,该怎么办?它不是一个完整的 HTML 解析项目,只需要一个正则表达式。你的答案是包含更多的导入并为此构建一个全新的框架?我每年做数百个项目。一半使用 DOM/XPath,另一半根本不能,并且需要 Regex。

总之,不要那么狭隘。参考 XPath/DOM 工具,但有助于回答问题。不要只是投反对票。我们不是尼安德特人,需要一直嘲笑很久以前发表的古老的“不要使用正则表达式解析 HTML”帖子。

答案如下:

首先,单纯形:

(?s)<div.*?>(.*?)</div>

需要一个特别命名的 div?

(?s)<div[^>]*?class="txt-block"[^>]*?>(.*?)</div>

想要节省 CPU 并避免不必要的回溯?

<div[^>]*?class="txt-block"[^>]*?>(([^<]*(?(?!</div>)<))*)</div>

以上假设您没有嵌套的 DIV 项。这就是不使用 Regex 的整个想法真正发挥作用的时候。除非您使用 C#.Net。在这种情况下,您只需这样做:

(?xm)
    (?>
        <(?<Tagname>div)[^>]*?class="txt-block"[^>]*>
)
(?(Tagname)
    (
        </(?(?!\k'Tagname')(?<-Tagname>))*\k'Tagname'>(?<-Tagname>)
    |
        (?>
            <(?<Tagname>[a-z][^\s>]*)[^>]*>
        )
    |
        [^<]+
    )+?
    (?(Tagname)(?!))
)

或者,单行版本:

(?m)(?><(?<Tagname>div)[^>]*?class="txt-block"[^>]*>)(?(Tagname)(</(?(?!\k'Tagname')(?<-Tagname>))*\k'Tagname'>(?<-Tagname>)|(?><(?<Tagname>[a-z][^\s>]*)[^>]*>)|[^<]+)+?(?(Tagname)(?!)))

选择你的毒药。正则表达式比人们想象的更强大和可靠。我发布的最复杂的示例无法在 Regex Buddy 中运行,但可以在任何 .Net 框架中运行。 Regex Buddy 不支持平衡组,这是一种 .Net 风格。

【讨论】:

+1 公平的回答,我觉得 Regex 是做 HTML 时的最后手段,但我仍然给 +1 以指出一些可以在有限情况下工作的选项。【参考方案2】:

使用正则表达式解析 HTML 不是一个好主意。尝试在 c# 中查找用于解析 HTML 的库。

在quick search 之后我想出了这个库:http://htmlagilitypack.codeplex.com/ 看来这个库有你需要的所有功能。

【讨论】:

以上是关于尝试在 C# 中使用正则表达式获取整个 <div>的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式 c# 获取捕获组的子组

正则表达式用特定格式 C# 替换整个单词

正则表达式使用 C# 从字符串中获取值

C#当中如何使用正则表达式获取某一标签的所有属性 属性数量不确定

使用 C# 解析 HTML 以获取内容

C# 中的正则表达式无法正常工作以进行数字检查 [重复]