我正在使用正则表达式来识别一些命名组。有少数情况下有多个具有不同模式的组。问题是将所有命名组都放入相应的列表中。限制是我不能有多个正则表达式,我不能多次调用执行正则表达式。我尝试过以下代码,但它总是返回第二种模式:
Regex reg = new Regex(@"(?<n1>pattern_n1_1) (?<n2>pattern_n2_1) (?<n1>pattern_n1_2) (?<n2>pattern_n1_2)", RegexOptions.IgnoreCase);
String str = "pattern_n1_1 pattern_n2_1 pattern_n1_2 pattern_n1_2";
List<String> matchedText = new List<string>();
List<String> string_n1 = new List<string>();
List<String> string_n2 = new List<string>();
MatchCollection mc = reg.Matches(str);
if (mc != null)
{
foreach (Match m in mc)
{
matchedText.Add(m.Value.Trim());
string_n1.Add(m.Groups["n1"].Value);
string_n2.Add(m.Groups["n2"].Value);
}
}
此处列表string_n1
和string_n2
各有一个元素。 string_n1
有&#34; pattern_n1_2&#34;并且string_n2
有&#34; pattern_n2_2&#34;。但是,我需要&#34; pattern_n1_1&#34;和&#34; pattern_n1_2&#34;在string_n1
和&#34; pattern_n2_1&#34;和&#34; pattern_n2_2&#34;在string_n2
答案 0 :(得分:2)
无需更改正则表达式。您只需要更改从捕获组中检索结果的方式。
由于您有多个同名的捕获组,为了检索在该名称下完成的所有捕获,您需要遍历Capture
中的所有Groups["n1"].Captures
,而不是访问单个捕获Groups["n1"].Value
。
MatchCollection mc = reg.Matches(str);
if (mc != null)
{
foreach (Match m in mc)
{
matchedText.Add(m.Value.Trim());
foreach (Capture c in m.Groups["n1"].Captures) {
string_n1.Add(c.Value);
}
foreach (Capture c in m.Groups["n2"].Captures) {
string_n2.Add(c.Value);
}
}
}
据我所知,这是.NET Regex API独有的功能。其他任何一种都没有提供API来完成重复捕获组的所有匹配:
^\w+(?: (\w+))+$
其他风格仅返回上例中捕获组1的最后一次捕获。 .NET允许您通过捕获组提取所有捕获。
虽然有些风格允许您为不同的捕获组定义相同的名称,但其他风格只允许您在通过组名查询时访问其中一个捕获。
答案 1 :(得分:0)
根据具体情况,以下可能可以满足您的需求,但不是通用解决方案:
Regex reg = new Regex(@"((?<n1>(pattern_n1_1|pattern_n1_2)) (?<n2>(pattern_n2_1|pattern_n1_2)) ){2}", RegexOptions.IgnoreCase);
这将捕获比原始更多一点,因为pattern_n1_2将被捕获为第四个&#34;组&#34;例如,在此版本中,但不是原始版本。