正则表达式提取特定 HTML 标记中的纯文本 [重复]

Posted

技术标签:

【中文标题】正则表达式提取特定 HTML 标记中的纯文本 [重复]【英文标题】:Regex to extract pure text within specific HTML tag [duplicate] 【发布时间】:2018-02-15 06:29:42 【问题描述】:

在这种情况下,我应该只使用一个正则表达式匹配。 请参阅以下 html 代码:

<html>
  <body>
    <p>This is some <strong>strong</strong> text</p>
  </body>
</html>

我想做一个可以返回This is some strong text 的正则表达式。在这种情况下,&lt;p&gt; 标记内的文本。

总体来说应该:

仅匹配两个 HTML 标记之间的文本。 排除两个标签内的 HTML 标签,但保留这些标签内的文本。

目前我知道:

&lt;p&gt;(.*)&lt;\/p&gt; 将匹配从&lt;p&gt;&lt;/p&gt; 的区域 &lt;[^&gt;]*&gt; 将匹配任何 HTML 标签

对我来说困难的部分是如何将两者结合起来(也许有更好的方法)。 你会怎么写这样的正则表达式?

【问题讨论】:

认真研究HtmlAgilityPack(免费,可通过 Nuget 获得)——它会让你变得更快乐! 也许像 HtmlAgilityPack (nuget.org/packages/HtmlAgilityPack) 这样的东西会更适合您的需求。 这是我学校的一项练习任务。 教正则表达式的例子真是太糟糕了。 ***.com/questions/1732348/… 作为老师的例子,添加一个&lt;br/&gt;,一个&lt;img src="smiley.gif" alt="Smiley face &lt;_&lt; and &gt;_&lt; and &gt;_&gt; &lt;3&lt;3" height="42" width="42"&gt;。让我们看看他的解决方案是如何解析的。 【参考方案1】:

真正的软件工程师如何解决这个问题:为正确的工作使用正确的工具,即不要使用正则表达式来解析 HTML

最直接的方法是使用 HTML 解析库,因为使用正则表达式解析即使是完全符合 XML 的也非常不简单,处理所有 HTML 边缘情况是一项非常困难的任务。


如果您的要求是“您必须使用正则表达式库从 &lt;p&gt; 元素中提取 innerHTML”,我非常更愿意将其拆分为两个任务:

1) 使用正则表达式提取容器元素及其 innerHTML。 (我展示的示例仅适用于获取已知标签的最外层元素。要提取任意嵌套项,您必须使用 https://blogs.msdn.microsoft.com/bclteam/2005/03/15/net-regular-expressions-regex-and-balanced-matching-ryan-byington/ 之类的技巧来匹配平衡表达式)

2) 使用简单的 Regex.Replace 去除所有标签内容

let html = @"<p>This is some <strong>strong</strong> text</p>
<p>This is some <b><em>really<strong>strong</strong><em></b> text</p>"

for m in Regex.Matches(html, @"<p>(.*?)</p>") do
    printfn "(%O)" (Regex.Replace(m.Groups.[1].Value, "<.*?>", ""))

(This is some strong text)
(This is some reallystrong text)

如果您受限于单个“Regex.Matches”调用,并且可以忽略嵌套 &lt;p&gt; 标记的可能性(幸运的是,在符合 HTML 的情况下,您不能嵌套 p s 但是这个解决方案不适用于像&lt;div&gt; 这样的包含元素)你应该能够通过文本部分的非贪婪匹配和包裹在&lt;p&gt;...&lt;/p&gt; 模式中的标签部分来做到这一点。 (注 1:这是 F#,但转换为 C# 应该很简单)(注 2:这依赖于 .NET 风格的正则表达式,如可堆叠组名和每个组的多个捕获)

let rx = @"
<p>
(?<p_text>
 (?:
   (?<text>[^<>]+)
   (?:<.*?>)+
 )*?
 (?<text>[^<>]+)?
)</p>
"
let regex = new Regex(rx, RegexOptions.IgnorePatternWhitespace)
for m in regex.Matches(@"
<p>This is some <strong>strong</strong> text</p>
<p>This is some <b><em>really<strong>strong</strong><em></b> text</p>
 ") do
    printfn "p content: %O" m
    for capture in m.Groups.["text"].Captures do
        printfn "text: %O" capture

p content: <p>This is some <strong>strong</strong> text</p>
text: This is some 
text: strong
text:  text
p content: <p>This is some <b><em>really<strong>strong</strong><em></b> text</p>
text: This is some 
text: really
text: strong
text:  text


请记住,上述两个示例都不适用于格式错误的 HTML 或相同标签嵌套在 itsel 中的情况

【讨论】:

【参考方案2】:

按照@Jimmy 的回答,以及关于如何“提取”文本的帖子标题,我想我会包含 Regex.Replace 的 C# 代码。

这段代码应该可以提取文本:

string HTML = "<html><body><p>This is some <strong>strong</strong> text</p></body></html>";

Regex Reg = new Regex("<[^>]*>");
String parsedText = Reg.Replace(HTML, "").Trim();

MessageBox.Show(parsedText);

显然这在两个标签之间并不完全匹配(它也会抓取段落标签之外的任何内容),但我建议替换功能是仅进行 ONE 匹配的最佳选择。

如果您只需要获取两个标签之间的内容,我认为您需要在两个表达式中执行此操作,正如@Jimmy 建议的那样。

我很想知道是否有人可以用一种表达方式理解所有内容,但我猜这就是他们在你们学校寻找的东西。

【讨论】:

以上是关于正则表达式提取特定 HTML 标记中的纯文本 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

C# 正则表达式提取html中的文本

构建正则表达式(RegEx)以提取 HTML 标记的文本 [重复]

PHP 正则表达式匹配 img ,PHP 正则提取或替换图片 img 标记中的任意属性。

使用正则表达式仅提取两个特定标记之间的数字

在 Python 中使用正则表达式从特定 xml 标记中提取特定值 [重复]

通过正则表达式删除嵌套在多个 html 标记中的特定单词