我在C#中有一个非常简单的正则表达式:
(var \= 0\;)
但是当我尝试将此匹配仅出现一次模式的字符串时,我会返回多个组。输入字符串是:
foo bar
var = 0;
foo
我得到了Regex对象返回的1个匹配,但在里面我看到两个组,每个组有1个捕获,这是我想要的字符串。 我需要正则表达式中的分组括号,因为这是更大的正则表达式的一部分,我需要将其作为一个组捕获。 我做错了什么?
修改
这是我使用的C#代码:
private const string REGEX = "(var \\= [0]\\;)";
MatchCollection matches = REGEX.Matches(inputStr);
foreach (Match m in matches)
{
foreach (Group g in m.Groups)
{
Console.WriteLine("group[" + g.Captures.Count + "]: '" + g.ToString() + "'");
}
}
这就是我得到的:
group[1]: 'var = 0;'
group[1]: 'var = 0;'
我的问题是,为什么我得到两组而不是一组?
编辑#2:
更复杂的模式显示了问题。模式:
# preceding comment
class
{
(param1 = "val1", param2 = "val2", param3 = val3)
}
[
# inside comment
setting1 = 0;
setting2 = 0;
]
我正在使用的正则表达式:(它可能不是最明显的,但如果要查看它,可以将其粘贴到正则表达式查看器中)
(\#[^\n]*)?(?:[\s\r\n]*)domain(?:[\s\r\n]*)\{(?:[\s\r\n]*)\((?:[\s\r\n]*)(((?:[\s\r\n]*)(accountName(?:[\s\r\n]*)\=(?:[\s\r\n]*)\"[^"]+\"[,]?)(?:[\s\r\n]*))|((?:[\s\r\n]*)(tableName(?:[\s\r\n]*)\=(?:[\s\r\n]*)\"[^"]+\"[,]?)(?:[\s\r\n]*))|((?:[\s\r\n]*)(cap(?:[\s\r\n]*)\=(?:[\s\r\n]*)[\d]+[,]?)(?:[\s\r\n]*))|((?:[\s\r\n]*)(MinPartitionCount(?:[\s\r\n]*)\=(?:[\s\r\n]*)[\d]+[,]?)(?:[\s\r\n]*)))+\)(?:[\s\r\n]*)\}(?:[\s\r\n]*)\[(?:[\s\r\n]*)(\#[^\n]*)?(?:[\s\r\n]*)((?:[\s\r\n]*)(IsSplitEnabled(?:[\s\r\n]*)\=(?:[\s\r\n]*)[0|1](?:[\s\r\n]*)\;)(?:[\s\r\n]*)|(?:[\s\r\n]*)(IsMergeEnabled(?:[\s\r\n]*)\=(?:[\s\r\n]*)[0|1](?:[\s\r\n]*)\;)(?:[\s\r\n]*))*(?:[\s\r\n]*)\]
我得到了:
group:1: '# preceding comment
domain
{
(param1 = "val1", param2 = "val2", param3 = val3)
}
[
# inside comment
setting1 = 0;
setting2 = 0;
]'
'roup:1: '# preceding comment
group:3: 'cap = 1200'
group:1: 'param1 = "val1", '
group:1: 'param1 = "val1",'
group:1: 'param2 = "val2", '
group:1: 'param2 = "val2",'
group:1: 'param3 = val3'
group:1: 'param3 = val3'
'roup:1: '# inside comment
group:2: 'setting1 = 0;
'
group:1: 'setting1 = 0;'
group:1: 'setting2 = 0;'
答案 0 :(得分:2)
根据文档,GroupCollection
的第一个元素是整个匹配,而不是()
创建的第一个组。
从备注部分here底部附近:
如果正则表达式引擎可以找到匹配的第一个元素 Groups属性返回的GroupCollection对象包含 与整个正则表达式模式匹配的字符串。 <每个后续元素>如果正则表达式包括捕获组,则表示捕获的组。
因此,根据您当前使用的RegEx,项目0和1都是相同的。要仅查看实际的组匹配,您可以跳过GroupCollection
的第一个元素,并仅处理您在RegEx中定义的组。
在调查了其他数据后,我想我可能已经找到了重复的原因。
我相信您看到多个Match
,因此外部foreach
循环运行两次,而不是一次。这是因为有两条单独的行“= 0;”在示例中。
这是LinqPad示例代码,显示找到2个匹配项,因此输出多个重复组。 (注意,我使用了你提供的简单正则表达式进行测试,因为长正则表达式没有提供任何匹配)
static string inputStr = "# preceding comment \r\n" +
"class\r\n" +
"{\r\n" +
" (param1 = \"val1\", param2 = \"val2\", param3 = val3)\r\n" +
"}\r\n" +
"[\r\n" +
" # inside comment\r\n" +
" setting1 = 0;\r\n" +
" setting2 = 0;\r\n" +
"]\r\n";
const string REGEX = "(\\= [0]\\;)";
void Main()
{
var regex = new System.Text.RegularExpressions.Regex(REGEX);
MatchCollection matches = regex.Matches(inputStr);
Console.WriteLine("Matches:{0}", matches.Count);
int matchCnt = 0;
foreach (Match m in matches)
{
int groupCnt = 0;
foreach (Group g in m.Groups)
{
Console.WriteLine("match[{0}] group[{1}]: Captures:{2} '{3}'", matchCnt, groupCnt, g.Captures.Count, g);
//g.Dump();
groupCnt++;
}
matchCnt++;
}
Console.WriteLine("Done!");
}
以下是此代码运行时LinqPad生成的输出:
Matches:2
match[0] group[0]: Captures:1 '= 0;'
match[0] group[1]: Captures:1 '= 0;'
match[1] group[0]: Captures:1 '= 0;'
match[1] group[1]: Captures:1 '= 0;'
Done!