我有以下正则表达式:
\{(\w+)(?:\{(\w+))+\}+\}
我需要它来匹配以下任何一个
{a{b}}
{a{b{c}}}
{a{b{c{d...}}}}
但是通过在最后一个上使用正则表达式,它只匹配两个组:a
和c
它不匹配b
和' c& #39;或其他任何可能介于两者之间的词语。
如何让小组匹配每个小组,如:
group #1: a
group #2: b
group #3: c
group #4: d
group #4: etc...
或喜欢
group #1: a
group #2: [b, c, d, etc...]
另外,我如何制作它以使左侧{
的数量相同,右侧有}
,否则不匹配?
感谢您的帮助,
大卫
答案 0 :(得分:2)
在.NET中,正则表达式可以1)检查平衡组,2)为组堆栈中的每个捕获组存储捕获集合。
如果以{
开头且以}
结尾的整个字符串包含以下正则表达式,则您可以仅提取每个^{(?:(?<c>[^{}]+)|(?<o>){|(?<-o>)})*(?(o)(?!))}$
中的所有文本平衡量的那些开/关花括号:
^
请参阅regex demo。
<强>详情:
{
- 字符串开头(?:
- 一个大括号(?<c>[^{}]+)
- 开始一组替代方案:
{
- 除了}
和|
以外的1个字符被捕获到&#34; c&#34;组(?<o>{)
- 或{
- |
匹配,并将值推送到组&#34; o&#34;堆(?<-o>})
- 或}
- 匹配)*
并从Group&#34; o&#34;中弹出一个值堆(?(o)(?!))
- 交替小组结束,重复0次以上}
- 一个条件构造,检查Group&#34; o&#34;堆栈是空的}
- 关闭$
var pattern = "^{(?:(?<c>[^{}]+)|(?<o>{)|(?<-o>}))*(?(o)(?!))}$";
var result = Regex.Matches("{a{bb{ccc{dd}}}}", pattern)
.Cast<Match>().Select(p => p.Groups["c"].Captures)
.ToList();
- 字符串结束。{a{bb{ccc{dd}}}}
[a, bb, ccc, dd]
的输出为{{a{bb{ccc{dd}}}}
而{
的输出(开头添加了{{1}}),结果为空。
答案 1 :(得分:2)
对于支持递归的正则表达式(PCRE,Ruby),您可以使用以下通用模式:
^({\w+(?1)?})$
它允许检查输入matches the defined pattern但是不捕获所需的组。有关详细信息,请参阅http://www.regular-expressions.info/recurse.html中的匹配均衡结构部分。
为了捕获组,我们可以将模式检查正则表达式转换为正向前导,在字符串((?:^(?=({\w+(?1)?})$)|\G(?!\A))
)的开头只检查一次,然后使用全局搜索捕获所有“单词”:
(?:^(?=({\w+(?1)?})$)|\G(?!\A)){(\w+)
a
,b
,c
等现在位于第二个捕获组中。
正则表达式演示:https://regex101.com/r/2wsR10/2。 PHP演示:https://ideone.com/UKTfcm。
<强>解释强>
(?:
- 交替小组的开始
^
- 字符串开头(?=
- 开始积极向前看({\w+(?1)?})
- 上面的通用模式$
- 字符串的enf )
- 结束了积极向前看|
- 或\G
- end of previous match (?!\A)
- 如果第一个选项失败,请确保之前的\G
与输入的开头不匹配)
- 交替小组结束{
- 按字面意思打开大括号(\w+)
- 在第二组中捕获的“字”。Ruby有不同的递归语法,正则表达式是:
(?:^(?=({\w+\g<1>?})$)|\G(?!\A)){(\w+)