我采用这种模式来匹配嵌套的 div:
(<div[^>]*>(?:\g<1>|.)*?<\/div>)
这很好用,正如您在 regex101 中看到的那样.
但是,当我用 C# 编写以下代码时:
Regex findDivs = new Regex("(<div[^>]*>(?:\\g<1>|.)*?<\\/div>)", RegexOptions.Singleline);
它抛出一个错误:
Additional information:
parsing "(<div[^>]*>(?:\g<1>|.)*?<\/div>)" -
Unrecognized escape sequence \g.
如您所见,\g
在 C# 中不起作用。那么我怎样才能匹配第一个子模式呢?
最佳答案
您正在寻找的是平衡组。这是正则表达式到 .NET 的一对一转换:
(?sx)<div[^>]*> # Opening DIV
(?> # Start of atomic group
(?:(?!</?div[^>]*>).)+ # (1) Any text other than open/close DIV
| <div[^>]*> (?<tag>) # Add 1 "tag" value to stack if opening DIV found
| </div> (?<-tag>) # Remove 1 "tag" value from stack when closing DIV tag is found
)*
(?(tag)(?!)) # Check if "tag" stack is not empty (then fail)
</div>
参见 regex demo
但是,您可能真的想使用 HtmlAgilityPack 来解析 HTML。
要点是获得一个 XPath,它将匹配所有没有同名祖先的 DIV 标签。你可能想要这样的东西(未经测试):
private List<string> GetTopmostDivs(string html)
{
var result = new List<KeyValuePair<string, string>>();
HtmlAgilityPack.HtmlDocument hap;
Uri uriResult;
if (Uri.TryCreate(html, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp)
{ // html is a URL
var doc = new HtmlAgilityPack.HtmlWeb();
hap = doc.Load(uriResult.AbsoluteUri);
}
else
{ // html is a string
hap = new HtmlAgilityPack.HtmlDocument();
hap.LoadHtml(html);
}
var nodes = hap.DocumentNode.SelectNodes("//div[not(ancestor::div)]");
if (nodes != null)
return nodes.Select(p => p.OuterHtml).ToList();
else
return new List<string>();
}
关于c# - 如何匹配 C# 中的第一个子模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37421193/