.Net Regex - 重复字符的最后一个

时间:2016-08-12 00:13:09

标签: c# regex

我正在尝试捕捉卷曲护腕内的所有东西,但在某些情况下可能会有多个护腕,我想要外部护腕。

例如:我想捕获{{this}}部分 我需要{{this}}作为捕获。

所以我选择({[^}]+}+)来捕获内部文本,但当然这会产生多个捕获{{this}{{this}}

所以我试着告诉正则表达式搜索这个短语,但前提是下一个字符不是大括号:({[^}]+}+)[^}]。这是有效的,除非捕获位于输入的末尾,在这种情况下它不起作用,因为它最终需要一个非}字符。

所以我尝试添加字符串结尾选项({[^}]+}+)[$|^}],但出于某种原因,这会再次捕获{{this}。我不知道为什么,它应该只捕获下一个char是输入结束还是没有花括号......

建议?

编辑:

为了清楚起见,我不是在寻找有效的嵌套括号,只是为了{和第一个匹配}之间的文本(没有嵌套!),但是可能会出现这样的情况,而不是一个打开/关闭括号有两个(所以{something}和{{something}}都需要被捕获。)

原因是原始文本总是有双括号{{}},但有时在正则表达式之前文本经过string.Format,在这种情况下双括号变为单括号。

3 个答案:

答案 0 :(得分:4)

通常,正则表达式不够强大。但是,.NET正则表达式引擎支持所谓的Atomic Grouping,它允许您处理具有平衡括号的组:

{(?>{(?<DEPTH>)|}(?<-DEPTH>)|[^}]+)*}(?(DEPTH)(?!))

答案 1 :(得分:2)

如果你想匹配大括号之间的所有文本,我认为这应该可以解决问题:

{+.*?}+

这匹配大括号之间的所有内容,采用所有连续括号和尽可能少的内部字符。

进一步说明:匹配1个或多个{{+,然后匹配任何数量.*但是为您提供最短的字符串?,最后匹配1+} }+。没有?,如果您有{a} {b},则它会与整个内容匹配,而不是{a}{b}

如果您不想在大括号之间留出空格,可以使用:

{+\S*?}+

如果您只想要信件,请使用\w代替\S

唯一没有验证的是使用相同数量的大括号。你需要吗?

结果比较(应该是评论)。

考虑{{{{{{this}}}}}Blabla,我明白了:

正则表达作者:c0d3rman

  • 匹配字符串:{{{{{{this}}}}}B
  • 群组:2({{{{{{this}}}}}B{{{{{{this}}}}}
  • 捕获:{{{{{{this}}}}}

正则表达作者:dasblinkenlight

  • 匹配字符串:{{{{{this}}}}}
  • 群组:2({{{{{this}}}}}{}
  • 捕获:{{{{{this}}}}}

注意:对称括号

正则表达作者:安德鲁

  • 匹配字符串:{{{{{{this}}}}}
  • 群组:{{{{{{this}}}}}
  • 捕获:{{{{{{this}}}}}

答案 2 :(得分:1)

您似乎在最后使用了一个字符类而不是非捕获组。试试:

({[^}]+}+)(?:$|[^}])

这是对最终尝试的一个非常小的修改,只是使用正确的语法。在您的最后一次尝试中,您有[$|^}]。这个问题是你不能在角色类|内有[]。大多数特殊字符在字符类中进行转义,但有几个例外,如果是第一个字符,则其中一个是^。因此,[$|^}]表示四个文字字符$|^}中的任何一个。我所做的是使用非捕获组(?:stuff)将语法更改为您的意图,此组不保存其内容,仅用于分组。因此,(?:$|[^}])表示行尾或非},如您所愿。

请注意,这不会平衡花括号(匹配开头和结尾的花括号)。