使用 RegEx 查找 HTML / XML 节点

Find HTML / XML node using RegEx

我正在解析许多 HTML 文档,并且在每个文档中都需要尝试提取一个英国邮政地址。为此,我使用 AngleSharp 解析 HTML,然后寻找具有与我的 RegEx 相匹配的 TextContent 的节点:

var parser = new HtmlParser();
var source =  "<html><head><title>Test Title</title></head><body><h1>Some example source</h1><p>This is a paragraph element and example postode EC1A 4NP</body></html>";
var document = parser.Parse(source);
Regex searchTerm = new Regex("([A-PR-UWYZ][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)");
var list = document.All.Where(m => searchTerm.IsMatch((m.TextContent ?? "").ToUpper()));

这 return 的 3 个结果,htmlbodyp 元素。我想要 return 的唯一元素是 p 元素,因为它具有正确匹配正则表达式的 innerText。一个页面上也可能有多个匹配项,所以我不能只 return 最后一个结果。我正在寻找 return 该元素中的文本(不在任何子节点中)与正则表达式匹配的任何元素。

编辑

我事先不知道文档结构甚至邮政编码所在的标签,这就是我使用正则表达式的原因。得到结果后,我计划遍历 dom 以获取地址的其余部分,因此我不想只将文档视为字符串

如果您希望在 well-formed HTML/XML 文档中提取特定节点,请查看利用 XPath。 MSDN

上有一些示例

您可以使用 HTML Tidy 到 "clean-up" 和 html 等实用程序库,如果还没有,请使其格式正确。

我快速浏览了一下解析器的文档。如果您只想检查 <p> 标签中的文本,您需要执行以下操作。

var list = document.All.Where(m => m.LocalName.ToUpper() == "P" && searchTerm.IsMatch((m.TextContent ?? "").ToUpper()));

好吧,最后我采取了不同的方法。我搜索 HTML 文档作为一个字符串,使用 RegEx 不是为了解析 HTML 而是为了找到精确的匹配值。一旦我有了那个值,就可以很简单地使用 xpath 表达式来 return 节点。在上面的示例中,正则表达式搜索 returns EC1A 4NP 和以下 XPATH:

//*[contains(text(),'EC1A 4NP')]

returns 所需的节点。为了简化 XPath,我从 AngleSharp 切换到 HtmlAgilityPack 以进行 HTML 解析