特定标签及其内容的正则表达式,按标签名称分组
Posted
技术标签:
【中文标题】特定标签及其内容的正则表达式,按标签名称分组【英文标题】:Regex for specifig tags and their content, groupped by the tag name 【发布时间】:2010-09-17 01:31:25 【问题描述】:这是输入(html,不是 xml):
... html content ...
<tag1> content for tag 1 </tag1>
<tag2> content for tag 2 </tag2>
<tag3> content for tag 3 </tag3>
... html content ...
我想获得 3 场比赛,每场比赛有两组。第一组将包含标签的名称,第二组将包含标签的内部文本。只有这三个标签,所以它不需要是通用的。
换句话说:
match.Groups["name"] would be "tag1"
match.Groups["value"] would be "content for tag 2"
有什么想法吗?
【问题讨论】:
注意更新的 HtmlAgilityPack 示例;我怀疑这可以满足您的需要。 【参考方案1】:我不明白您为什么要为此使用匹配组名称。
这是一个正则表达式,它将标记名称和标记内容匹配为编号的子匹配项。
<(tag1|tag2|tag3)>(.*?)</$1>
这是一个带有 .NET 样式组名称的变体
<(?'name'tag1|tag2|tag3)>(?'value'.*?)</\k'name'>.
编辑
RegEx 根据问题作者的说明进行了改编。
【讨论】:
托马拉克,太棒了!完美运行,正是我需要的。我试过升级你,但我必须注册。我也尝试接受答案,但没有任何反应。 无论如何都欢迎你。 ;-) 但是,如果您想报答,请您注册并接受答案。【参考方案2】:正则表达式可能是:
/<([^>]+)>([^<]+)<\/\1>/
但这很笼统,因为我对 .NET 的转义机制了解不多。翻译它:
第一组匹配 之间的第一个标签的名称 第二组匹配内容(从>到下一个 结束检查第一个标签是否关闭HTH
【讨论】:
请注意,由于标签内容的 [^ 当我排除打开和关闭/
时,这个正则表达式在 VS2017 中为我工作(使用查找和替换)【参考方案3】:
感谢所有但没有一个正则表达式工作。 :( 也许我不够具体,抱歉。这是我要解析的确切 html:
...some html content <b> etc </b> ...
<user> hello <b>mitch</b> </user>
...some html content <b> etc </b> ...
<message> some html <i>message</i> <a href....>bla</a> </message>
...some html content <b> etc </b> ...
我希望现在更清楚了。我在 USER 和 MESSAGE 标签之后。
我需要两场比赛,每场比赛有两组。第一组给我标签名称(用户或消息),第二组给我标签的整个内部文本。
【讨论】:
我的回答做了一些修改,请重试! 那不是 HTML... 无论如何都不是标准 DTD。【参考方案4】:数据是正确的 xml,还是只是看起来像?
如果是 html,那么 HTML Agility Pack 值得研究——它提供了一个 DOM(类似于 XmlDocument),您可以使用它来查询数据:
string input = @"<html>...some html content <b> etc </b> ...
<user> hello <b>mitch</b> </user>
...some html content <b> etc </b> ...
<message> some html <i>message</i> <a href....>bla</a> </message>
...some html content <b> etc </b> ...</html>";
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(input);
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//user | //message"))
Console.WriteLine("0: 1", node.Name, node.InnerText);
// or node.InnerHtml to keep the formatting within the content
这个输出:
user: hello mitch
message: some html message bla
如果您想要格式化标签,请使用 .InnerHtml 而不是 .InnerText。
如果是 xml,那么要使用 xml 的全谱进行编码,最好使用 xml 解析器。对于中小型 xml,将其加载到诸如 XmlDocument 之类的 DOM 中就可以了 - 然后查询节点(例如,“//*”)。对于大型 xml,XmlReader 可能是一种选择。
如果数据不必担心完整的xml,那么一些简单的正则表达式应该不会太棘手......一个简化的例子(没有属性,没有命名空间,没有嵌套的xml)可能是:
string input = @"blah <tag1> content for tag 1 </tag1> blop
<tag2> content for tag 2 </tag2> bloop
<tag3> content for tag 3 </tag3> blip";
const string pattern = @"<(\w+)>\s*([^<>]*)\s*</(\1)>";
Console.WriteLine(Regex.IsMatch(input, pattern));
foreach(Match match in Regex.Matches(input, pattern))
Console.WriteLine("0: 1", match.Groups[1], match.Groups[2]);
【讨论】:
数据不是有效的xml,而是html页面。 这看起来很有趣,我去看看,tnx。【参考方案5】:问题是人们用来匹配标签内的东西的 ([^
这里是 Tomalak 正则表达式的一个稍微更健壮的版本,允许属性和空格:
Regex tagRegex = new Regex(@"<\s*(?<tag>" + string.Join("|", tags) + @")[^>]*>(?<content>.*?)<\s*/\s*\k<tag>\s*>", RegexOptions.IgnoreCase);
显然,如果您只需要使用一组特定的标签,您可以替换
string.Joing("|", tags)
使用硬编码管道分隔的标签列表。
正则表达式的限制是,如果您尝试匹配嵌套在另一个标签中的一个标签,它将只匹配外部标签。即
abc def ghi
它将匹配外部用户标签,但不匹配内部消息标签。
它也不处理在属性中引用的 >,如下所示:
它只会匹配
将成为标签内容的一部分。
【讨论】:
【参考方案6】:这将为您提供所需的命名捕获组。但是,它不适用于嵌套标签。
/<(?<name>[^>]+)>(?<value>[^<]+)</\1>/
【讨论】:
以上是关于特定标签及其内容的正则表达式,按标签名称分组的主要内容,如果未能解决你的问题,请参考以下文章
用于查找 HTML 标签及其内容的正则表达式的否定 - java