考虑这个正则表达式:
(?:([A-Z][0-9a-z]*)+?)
当应用于字符串“A1BaaC2d”时,它给了我3组:“A1”,“Baa”和“C2d”
但是当我应用起始和结束字符串锚时,即^(?:( [A-Z] [0-9a-z] *)+?)$它不再正常工作。我猜这是一个引用问题(hense额外的分组,我尝试过非捕获和原子)。但我无法解决这个问题。如何获取我的组并验证总字符串没有任何前导或尾随字符。
仅供参考,这是.net正则表达式。
答案 0 :(得分:3)
让我们把它简化为基本要素:
([A-Z][0-9a-z]*)+
(我摆脱了外部的非捕获组,因为它对结果没有影响,我暂时从量词中删除了?
。)你得到的是一个正则表达式一个捕获组。由于+
量词,该组中的子表达式必须至少匹配一次,但默认情况下量词是贪婪的,因此它实际上与您的输入匹配三次。这是细分:
Match 1 = A1BaaC2d
Group 1 = C2d
Capture 1 = A1
Capture 2 = Baa
Capture 3 = C2d
(“组1”是指该组捕获的最终值。在大多数正则表达式/工具中,这是您将获得的所有信息; .NET的独特之处在于它允许您打破所有中间捕获。)
但是,您使用量词的非贪婪版本+?
:
([A-Z][0-9a-z]*)+?
它仍然必须匹配(和捕获)[A-Z][0-9a-z]*
至少一次,但现在它停在那里,除非有什么东西迫使它继续。什么都没有,所以你得到三个单独的匹配,每个包含一个 Capture :
Match 1 = A1
Group 1 = A1
Capture 1 = A1
Match 1 = Baa
Group 1 = Baa
Capture 1 = Baa
Match 1 = C2d
Group 1 = C2d
Capture 1 = C2d
然后你添加了锚点:
^([A-Z][0-9a-z]*)+?$
现在,每个匹配必须从字符串的开头开始,并在字符串的结尾处结束。要实现这一点,正则表达式引擎会覆盖+?
的非贪婪,并且您将返回一个与三个捕获的匹配:
Match 1 = A1BaaC2d
Group 1 = C2d
Capture 1 = A1
Capture 2 = Baa
Capture 3 = C2d
以下是我用于生成此输出的代码的最终版本。请注意,您并不需要使用非贪婪的正则表达式; ^([A-Z][0-9a-z]*)+$
也可以正常运作。
static void Main()
{
string source = "A1BaaC2d";
Regex r = new Regex(@"^([A-Z][0-9a-z]*)+?$");
foreach (Match m in r.Matches(source))
{
int x = 1;
Console.WriteLine(@"Match {0} = {1}", x++, m.Value);
Console.WriteLine(@"Group 1 = {0}", m.Groups[1]);
int y = 1;
foreach (Capture c in m.Groups[1].Captures)
{
Console.WriteLine(@"Capture {0} = {1}", y++, c.Value);
}
Console.WriteLine();
}
}