c# regex中命名捕获的问题

本文关键字:问题 regex | 更新日期: 2023-09-27 17:50:30

我已经纠结了一段时间了

var matches = Regex.Matches("<h2>hello world</h2>",
    @"<(?<tag>[^'s/>]+)(?<innerHtml>.*)(?<closeTag>[^'s>]+)>",
    RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline);
string tag = matches[0].Groups["tag"].Value; // "h2"
string innerHtml = matches[0].Groups["innerHtml"].Value; // ">hello world</h"
string closeTag = matches[0].Groups["closeTag"].Value; // "2"

可以看出,tag符合预期,而innerHtmlcloseTag则不符合预期。任何建议吗?谢谢。

输入字符串可能不同,这是另一种情况"<div class='myclass'><h2>hello world</h2></div>"

c# regex中命名捕获的问题

尝试在捕获组之外匹配></,像这样:

var matches = Regex.Matches("<h2>hello world</h2>",
    @"<(?<tag>[^'s/>]+)>(?<innerHtml>.*)</(?<closeTag>[^'s>]+)>",
    RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline);

更新更具体的例子,应该更灵活:

var matches = Regex.Matches(
    "<div class='myclass'><h2>hello world</h2></div>",
    @"<(?<tag>[^'s>]+)               #Opening tag
        's*(?<attributes>[^>]*)'s*>  #Attributes inside tag (optional)
      (?<innerHtml>.*)               #Inner Html
      </(?<closeTag>'1)>             #Closing tag, must match opening tag",
    RegexOptions.IgnoreCase | 
    RegexOptions.Compiled | 
    RegexOptions.Multiline |
    RegexOptions.IgnorePatternWhitespace);
string tag = matches[0].Groups["tag"].Value;             // "div"
string attr = matches[0].Groups["attributes"].Value;     // "class='myclass'"
string innerHtml = matches[0].Groups["innerHtml"].Value; // "<h2>hello world</h2>"
string closeTag = matches[0].Groups["closeTag"].Value;   // "div"

您需要Singleline选项,而不是MultilineSingleline使.能够匹配换行符,而Multiline改变锚(^$)的行为,您没有使用它们。

另外,如果您希望结束标记具有与开始标记相同的名称,则应该使用反向引用。这里我使用''作为名称分隔符,而不是<>,以减少混淆:

var matches = Regex.Matches("<h2>hello world</h2>",
    @"<(?'tag'[^/>]+)(?'innerHtml'.*)</'k'tag'>",
    RegexOptions.IgnoreCase | RegexOptions.Singleline);

你不需要Compiled选项。它所做的只是增加了创建Regex对象的成本,以提高您几乎肯定不需要也不会注意到的性能。