使用正则表达式在多个 HTML 标记之间获取文本 [重复]
Posted
技术标签:
【中文标题】使用正则表达式在多个 HTML 标记之间获取文本 [重复]【英文标题】:Using regex to get text between multiple HTML tags [duplicate] 【发布时间】:2013-04-06 23:46:54 【问题描述】:使用正则表达式,我希望能够获取多个 DIV 标记之间的文本。例如,以下内容:
<div>first html tag</div>
<div>another tag</div>
会输出:
first html tag
another tag
我使用的正则表达式模式只匹配我的最后一个 div 标签并且错过了第一个。 代码:
static void Main(string[] args)
string input = "<div>This is a test</div><div class=\"something\">This is ANOTHER test</div>";
string pattern = "(<div.*>)(.*)(<\\/div>)";
MatchCollection matches = Regex.Matches(input, pattern);
Console.WriteLine("Matches found: 0", matches.Count);
if (matches.Count > 0)
foreach (Match m in matches)
Console.WriteLine("Inner DIV: 0", m.Groups[2]);
Console.ReadLine();
输出:
找到的匹配项:1
内部 DIV:这是另一个测试
【问题讨论】:
这项任务是否必须使用正则表达式? HTML 是上下文无关文法,不能用正则表达式解析。很多时候你可以接近,但你最好使用 HTML 解析器。见***.com/a/1732454/2022565 【参考方案1】:用非贪婪匹配替换你的模式
static void Main(string[] args)
string input = "<div>This is a test</div><div class=\"something\">This is ANOTHER test</div>";
string pattern = "<div.*?>(.*?)<\\/div>";
MatchCollection matches = Regex.Matches(input, pattern);
Console.WriteLine("Matches found: 0", matches.Count);
if (matches.Count > 0)
foreach (Match m in matches)
Console.WriteLine("Inner DIV: 0", m.Groups[1]);
Console.ReadLine();
【讨论】:
它找到了两个匹配项,但在我的程序上显示空值 上面的代码应该可以工作,注意它的 m.Groups[1] 而不是 m.Groups[2] ,因为我改变了一点,因为没有理由捕获标签本身。 rubular.com/r/XQrcobmfAK【参考方案2】:首先请记住,在 HTML 文件中,您将有一个换行符(“\n”),您没有将它包含在您用来检查正则表达式的字符串中。
其次带你正则表达式:
((<div.*>)(.*)(<\\/div>))+ //This Regex will look for any amount of div tags, but it must see at least one div tag.
((<div.*>)(.*)(<\\/div>))* //This regex will look for any amount of div tags, and it will not complain if there are no results at all.
也是寻找此类信息的好地方:
http://www.regular-expressions.info/reference.html
http://www.regular-expressions.info/refadv.html
梅曼
【讨论】:
【参考方案3】:简而言之,您无法在所有情况下都正确执行此操作。总会有一些有效 HTML 的情况,正则表达式无法提取您想要的信息。
原因是因为 HTML 是一种上下文无关语法,它是一个比正则表达式更复杂的类。
这是一个例子——如果你有多个堆叠的 div 怎么办?
<div><div>stuff</div><div>stuff2</div></div>
作为其他答案列出的正则表达式将抓取:
<div><div>stuff</div>
<div>stuff</div>
<div>stuff</div><div>stuff2</div>
<div>stuff</div><div>stuff2</div></div>
<div>stuff2</div>
<div>stuff2</div></div>
因为这就是正则表达式在尝试解析 HTML 时所做的事情。
您无法编写一个能够理解如何解释所有情况的正则表达式,因为正则表达式无法做到这一点。如果您正在处理一组非常具体的受限 HTML,这可能是可能的,但您应该牢记这一事实。
更多信息:https://***.com/a/1732454/2022565
【讨论】:
【参考方案4】:你看过Html Agility Pack(见https://***.com/a/857926/618649)吗?
CsQuery 看起来也很有用(基本上使用 CSS 选择器样式的语法来获取元素)。见https://***.com/a/11090816/618649。
CsQuery 基本上是“用于 C# 的 jQuery”,这几乎是我用来查找它的确切搜索条件。
如果您可以在 Web 浏览器中执行此操作,您可以轻松地使用 jQuery,使用类似于 $("div").each(function(idx) alert( idx + ": " + $(this).text());
的语法(只是您显然会将结果输出到日志或屏幕,或者使用它进行 Web 服务调用,或任何你需要做的事情)。
【讨论】:
没有任何解释或评论的反对票。谢谢!事实是 HTML/XML 是众所周知的使用 Regex 处理的痛苦。并不是说你做不到,我当然在很多场合都做过,但是 CSS 选择器语法是一个更简洁的命题。【参考方案5】:我认为这段代码应该可以工作:
string htmlSource = "<div>first html tag</div><div>another tag</div>";
string pattern = @"<div[^>]*?>(.*?)</div>";
MatchCollection matches = Regex.Matches(htmlSource, pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
ArrayList l = new ArrayList();
foreach (Match match in matches)
l.Add(match.Groups[1].Value);
【讨论】:
【参考方案6】:由于其他人没有提到HTML tags with attributes
,这是我的解决方案:
// <TAG(.*?)>(.*?)</TAG>
// Example
var regex = new System.Text.RegularExpressions.Regex("<h1(.*?)>(.*?)</h1>");
var m = regex.Match("Hello <h1 style='color: red;'>World</h1> !!");
Console.Write(m.Groups[2].Value); // will print -> World
【讨论】:
【参考方案7】:我希望下面的正则表达式可以工作:
<div.*?>(.*?)<*.div>
你会得到你想要的输出
这是一个测试 这是另一个测试
【讨论】:
以上是关于使用正则表达式在多个 HTML 标记之间获取文本 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用正则表达式和 PHP 替换两个 HTML 标记之间的文本? [复制]