正则表达式提取特定 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
的正则表达式。在这种情况下,<p>
标记内的文本。
总体来说应该:
仅匹配两个 HTML 标记之间的文本。 排除两个标签内的 HTML 标签,但保留这些标签内的文本。目前我知道:
<p>(.*)<\/p>
将匹配从<p>
到</p>
的区域
<[^>]*>
将匹配任何 HTML 标签
对我来说困难的部分是如何将两者结合起来(也许有更好的方法)。 你会怎么写这样的正则表达式?
【问题讨论】:
认真研究HtmlAgilityPack
(免费,可通过 Nuget 获得)——它会让你变得更快乐!
也许像 HtmlAgilityPack (nuget.org/packages/HtmlAgilityPack) 这样的东西会更适合您的需求。
这是我学校的一项练习任务。
教正则表达式的例子真是太糟糕了。 ***.com/questions/1732348/…
作为老师的例子,添加一个<br/>
,一个<img src="smiley.gif" alt="Smiley face <_< and >_< and >_> <3<3" height="42" width="42">
。让我们看看他的解决方案是如何解析的。
【参考方案1】:
真正的软件工程师如何解决这个问题:为正确的工作使用正确的工具,即不要使用正则表达式来解析 HTML
最直接的方法是使用 HTML 解析库,因为使用正则表达式解析即使是完全符合 XML 的也非常不简单,处理所有 HTML 边缘情况是一项非常困难的任务。
如果您的要求是“您必须使用正则表达式库从
<p>
元素中提取 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”调用,并且可以忽略嵌套 <p>
标记的可能性(幸运的是,在符合 HTML 的情况下,您不能嵌套 p
s 但是这个解决方案不适用于像<div>
这样的包含元素)你应该能够通过文本部分的非贪婪匹配和包裹在<p>...</p>
模式中的标签部分来做到这一点。 (注 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 标记中的纯文本 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
构建正则表达式(RegEx)以提取 HTML 标记的文本 [重复]
PHP 正则表达式匹配 img ,PHP 正则提取或替换图片 img 标记中的任意属性。