正则表达式忽略嵌套分隔符上的匹配

时间:2013-11-30 23:28:26

标签: c# .net regex

我有一个输入字符串,如下所示:

var format = "{0}({1:2}({*:8})){2:3}({3:16})";

对于“你为此做什么”问题
上述格式告诉我们的内容与string.Format(string, args)方法非常类似,但有一些修改。

  • {0}是插入索引
  • {1:2}是具有指定长度(以字节为单位)的插入索引
  • ({3:16})是一个分组插入索引,它保留了匹配序列的副本

预期输出图表:

  • {0}
  • ({1:2}({*:8}))
  • {2:3}
  • ({3:16})

我现在得到的是什么:

  • {0}
  • ({1:2}
  • ({*:8}))
  • {2:3}
  • ({3:16})

我正在使用的正则表达式:

var regExpr = @"\(?\{\(*([^/}]+)\)*\}\)?";

顺便说一句,因为我刚才正在学习RegEx,所以我期待对表达效率的评论。

2 个答案:

答案 0 :(得分:1)

使用正则表达式通常是不可能的,但请阅读.NET中的Balancing Group Definition扩展名。

答案 1 :(得分:1)

是的,我认为我找到了一个解决方案 - 这可能是一种非常低效的模式,但是我对它是否可以完成感到好奇:

(((?<r>\{)|(?<-r>\})|(?<b>\()|(?<-b>\))|[^{}()]))+?(?(r)(?!))(?(b)(?!))

Working On RegexHero(.NET Regex Tester)Also tested here

<强>解释

首先我们有(?<r>\{)|(?<-r>\})|(?<b>\()|(?<-b>\)

这些是平衡组。对于找到的每个{,它会将匹配项添加到r组,然后对于每个},它会从r组中删除该匹配项。 (组中的)b也是如此。

然后,交替的最后部分是[^{}()],它与其他所有内容相匹配 - 即括号内可能出现的任何内容。

最后我们有(?(r)(?!))(?(b)(?!))(您可能可以使用(?(r|b)(?!)),但它在我使用的2个测试者中的一个上搞砸了结果。这是一个if..then构造,它会检查rb组中是否有任何内容,如果有(?!) - 是否为负面预测,总是会返回假。如果括号不平衡,这会使匹配返回false。

由于交替后+是一个懒惰的+?,它会匹配保持括号平衡的最短段。

至少在RegexHero上匹配:

\1 {0}
\2 ({1:2}({*:8}))
\3 {2:3}
\4 ({3:16})