我在pickaxe Ruby书中找到了一个用于寻找平衡括号表达式的正则表达式,我正在尝试在它上面建立一个匹配平衡括号/括号/ parens的正则表达式。
原文:
re = /
\A
(?<brace_expression>
{
(
[^{}] # anything other than braces
| # ...or...
\g<brace_expression> # a nested brace expression
)*
}
)
\Z
/x
到目前为止我的版本:
re = /
\A
(?<brace_expression>
(?:
(?<brace> { ) | (?<bracket> \[ ) | ( \( )
)
(
[^{}\[\]()] # anything other than braces
| # ...or...
\g<brace_expression> # a nested brace expression
)*
(?(<brace>) } | (?(<bracket>) \] | \) ) )
)
\Z
/x
它正确地匹配“{xyz}”,“[xyz]”,“(xyz)”,并且正确地无法匹配像“{xyz]”之类的东西,但递归并不像我期望的那样。它无法匹配像“{[]}”这样的嵌套大括号表达式。我错过了什么?
答案 0 :(得分:1)
有趣的问题。您当前的模式看起来非常好。如果使用交替而不是在与递归一起使用时似乎不可靠的条件,那该怎么办呢?
re = /
\A( # start group 1
\(([^)(\]\[}{]+|\g<1>)*+\)| # parens & set group 2
\[\g<2>*+\]| # brackets
\{\g<2>*+\} # braces
)\z # group 1 end
/x
\g<1>
是subexpression call到第一组,它保存了开始和结束之间的模式。\g<2>
是对第2组的调用,其中包含reducing the pattern的[^)(\]\[}{]+|\g<1>
。*+
是一个possessive quantifier,用于在不平衡时提高失败率。