当谈到 .NET 的正则表达式语言时,我不太清楚“组”和“捕获”之间的区别。考虑以下 C# 代码:
MatchCollection matches = Regex.Matches("{Q}", @"^\{([A-Z])\}$");
我希望这会导致一次捕获字母“Q”,但如果我打印返回的 MatchCollection
的属性,我会看到:
matches.Count: 1
matches[0].Value: {Q}
matches[0].Captures.Count: 1
matches[0].Captures[0].Value: {Q}
matches[0].Groups.Count: 2
matches[0].Groups[0].Value: {Q}
matches[0].Groups[0].Captures.Count: 1
matches[0].Groups[0].Captures[0].Value: {Q}
matches[0].Groups[1].Value: Q
matches[0].Groups[1].Captures.Count: 1
matches[0].Groups[1].Captures[0].Value: Q
这里到底发生了什么?我知道整个比赛也有一个捕获,但是这些组是如何进入的?为什么 matches[0].Captures
不包含字母“Q”的捕获?
最佳答案
您不会是第一个对此感到模糊的人。这就是著名的 Jeffrey Friedl不得不说一下(第 437 页以上):
Depending on your view, it either adds an interesting new dimension to the match results, or adds confusion and bloat.
进一步:
The main difference between a Group object and a Capture object is that each Group object contains a collection of Captures representing all the intermediary matches by the group during the match, as well as the final text matched by the group.
几页之后,这是他的结论:
After getting past the .NET documentation and actually understanding what these objects add, I've got mixed feelings about them. On one hand, it's an interesting innovation [..] on the other hand, it seems to add an efficiency burden [..] of a functionality that won't be used in the majority of cases
换句话说:它们非常相似,但偶尔您会发现它们的用途。在你长出另一把白 mustache 之前,你甚至可能会喜欢上 Captures...
由于以上内容和其他帖子中的内容似乎都无法真正回答您的问题,请考虑以下内容。将捕获视为一种历史跟踪器。当正则表达式匹配时,它从左到右遍历字符串(暂时忽略回溯),当它遇到匹配的捕获括号时,它会将其存储在 $x
中(x 是任何数字),比方说 $1
。
普通的正则表达式引擎,当要重复捕获括号时,将丢弃当前的 $1
并将其替换为新值。不是 .NET,它将保留此历史记录并将其放置在 Captures[0]
中。
如果我们将您的正则表达式更改为如下所示:
MatchCollection matches = Regex.Matches("{Q}{R}{S}", @"(\{[A-Z]\})+");
您会注意到第一个 Group
将有一个 Captures
(第一个组始终是整个匹配项,即等于 $0
) 并且第二组将保存 {S}
,即只有最后一个匹配组。然而,这里有一个问题,如果你想找到其他两个捕获,它们在 Captures
中,其中包含 {Q}
{ 的所有中间捕获R}
和 {S}
。
如果您想知道如何从多重捕获中获取信息,它只显示与字符串中明显存在的单个捕获的最后匹配,您必须使用 Captures
。
关于您的最后一个问题的最后一句话:总比赛总是有一个总捕获,不要将其与各个小组混在一起。捕获仅在组内有趣。
关于c# - .NET 正则表达式中的 "groups"和 "captures"有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3320823/