我写了这个正则表达式:
var cellPattern = new Regex(@"(?(?=\d+)\d+|\|)\s(.)\s", RegexOptions.Compiled | RegexOptions.Multiline);
从这个字符串中获取单元格:
string field =
" A B C D E \n" +
"1 | X | | | \n" +
" ---+---+---+---+---\n" +
"2 | | | | \n" +
" ---+---+---+---+---\n" +
"3 | O | | | \n" +
" ---+---+---+---+---\n" +
"4 | | | X | \n" +
" ---+---+---+---+---\n" +
"5 | | | | \n" +
"O >>> ";
我正在执行cellPattern.Matches(field);
它返回MatchCollection有25个匹配,但是为什么所有匹配都有一个空字符串作为第一组?
P.S .: 如果我使用命名匹配的子表达式,一切都按我想要的方式工作:所有匹配的网格单元格为“单元格”组:
var cellPattern = new Regex(@"(?(?=\d+)\d+|\|)\s(?<cell>.)\s", RegexOptions.Compiled | RegexOptions.Multiline);
P.P.S:我的项目框架是.NET Framework 4.5.2
P.P.P.S:在this site上,您还可以看到此行为
答案 0 :(得分:1)
这是.NET框架中的一个错误。然后使用(?(?= ) )
,它会忽略下一组的内容,但它仍然会计入组的数量。
当它看到(?(
时会设置一个标志来忽略下一个组,期望看到(?(expression) ... | ... )
,而是有一个(?= ... )
,所以该标志直到下一个才会重置捕获组。
修复方法是命名该组,添加一个虚拟组:
(?(?=\d+)\d+|\|)()\s(.)\s
或添加其他级别的parens:
(?((?=\d+))\d+|\|)\s(.)\s
在这种情况下,您还可以删除条件:
(?:\d+|\|)()\s(.)\s