我正在使用C#Regex类。我试图从一个分裂两个字符串。源(输入)字符串按以下方式构造:
第一部分必须匹配PO | P | S | [1-5](采用正则表达式语法)。
第二部分可以是VP | GZ | GAR | PP | NAD | TER | NT | OT | LO(再次,正则表达式语法)。第二部分可以发生零次或一次。
可接受的例子是“PO”(一组),“POGAR”(两组PO + GAR),“POT”(P + OT)......
所以我使用了以下正则表达式:
Regex r = new Regex("^(?<first>PO|P|S|[1-5])(?<second>VP|GZ|GAR|PP|NAD|TER|NT|OT|LO)?$");
Match match = r.Match(potentialToken);
当potentialToken为“PO”时,它返回3组!为什么?我只期待一组(第一组)。
match.Groups是{“PO”,“PO”,“”}
命名组正常 - match.Groups [“first”]返回1个实例,而match.Groups [“second”]。成功为假。
答案 0 :(得分:1)
即使您没有任何捕获组,RegularExpression也始终会在索引0处有一个“Group 0”组。
“组0”将等于正则表达式所做的整个匹配(Match.Value
)。
然后在你的情况下你得到3组,因为"Group 0" + "Group first" + "Group second"
。如上所述,“第二组”是一个可选组,因此当它不参与主题.Net正则表达式引擎标记"Group second".Success = false
时。我在这里看不出任何惊喜。这是预期的行为。
答案 1 :(得分:1)
使用编号的组时,第一个组始终是完整的匹配(子)字符串(参见docs - “Groups属性返回的GroupCollection对象的第一个元素包含一个与整个匹配的字符串正则表达式模式“),即在您的情况下PO
。
Groups
中的第二个元素是第一个命名组的捕获,第三个元素是第二个命名组的捕获 - 就像您可以按名称检索的两个捕获一样。如果您检查编号组的Success
,您会看到最后一个元素(与您的第二个命名组匹配的元素)的Success
值也为false
。您可以将其解释为“该组存在,但它与任何内容都不匹配”。
要确认这一点,请查看此测试代码的输出:
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
Regex r = new Regex("^(?<first>PO|P|S|[1-5])(?<second>VP|GZ|GAR|PP|NAD|TER|NT|OT|LO)?$");
Match match = r.Match("PO");
for (int i = 0; i < match.Groups.Count; i++) {
Console.WriteLine(string.Format("{0}: {1}; {2}", i, match.Groups[i].Success, match.Groups[i].Value));
}
}
}
您可以运行here。