Regex为specifig标记及其内容,groupped通过的标签名
题
这里的输入(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"
任何想法?
解决方案
我不明白你为什么要使用匹配组名。
这是一个正则表达式,它将标记名称和标记内容与编号的子匹配匹配。
<(tag1|tag2|tag3)>(.*?)</$1>
以下是.NET样式组名称
的变体<(?'name'tag1|tag2|tag3)>(?'value'.*?)</\k'name'>.
修改
RegEx根据问题作者的说明进行了调整。
其他提示
Regex为这可能是:
/<([^>]+)>([^<]+)<\/\1>/
但它总为我不知道很多关于逃跑的机构。网。把它翻译:
- 第一组相匹配的第一个标记的姓名之间 < 并>
- 第二组的内容相匹配(从>到下一个 <
- 底检查,如果第一个标记就是封闭的
禾田
感谢所有正则表达式都没有工作。 :(也许我不够具体,抱歉。这是我正在尝试解析的确切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标签。
我需要获得两场比赛,每场比赛有两组。第一组wpould给我标签名称(用户或消息),第二组给我标签的整个内部文本。
数据是正确的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中就可以了 - 然后查询节点(例如,<!> quot; // * <!> quot;)。对于巨大的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]);
}
问题在于([^ <!> lt;] *)人们用来匹配标签内的东西与开头<!> lt;匹配嵌套标记,然后嵌套标记的结束标记与外部标记不匹配,因此正则表达式失败。
这是一个稍微强大的Tomalak正则表达版本,允许属性和空格:
Regex tagRegex = new Regex(@"<\s*(?<tag>" + string.Join("|", tags) + @")[^>]*>(?<content>.*?)<\s*/\s*\k<tag>\s*>", RegexOptions.IgnoreCase);
显然,如果您只需要使用一组特定的标签,则可以替换
string.Joing("|", tags)
使用硬编码管道分隔标签列表。
正则表达式的限制是,如果你有一个标签,你试图匹配嵌套在另一个标签内,它只会匹配外标签。即。
LT <!>; <!>用户GT; ABC LT <!>;消息GT <!>; DEF LT <!>; <!> /消息GT; GHI LT <!>; <!> /用户GT;
它将匹配外部用户标记,但不匹配内部消息标记。
它也不会处理<!> gt;中引用的属性,如:
<!> lt; user attrib = <!> quot; oops <!> gt; <!> quot; <!> gt;
它将匹配
<!> lt; user attrib = <!> quot; oops <!> gt;
作为标签和
QUOT <!>; GT <!>;
将成为代码内容的一部分。
这将为您提供所需的命名捕获组。但是,它不适用于嵌套标记。
/<(?<name>[^>]+)>(?<value>[^<]+)</\1>/