我需要解析以下形式的表达式:
(S(A(B(D xyz))(C m)))
(的量总是等于)的量,但在(S)之间可以有任意数量的开括号和右括号对。在这种情况下,我想提取(A(B(D xyz))(C m))。文件中可能有任意数量的(S)子句,所以我不能简单地进行^(S。*)$类型的模式匹配。
如果我知道(S)之间可能的开括号和右括号对的数量,这不会那么困难,但我不知道如何编写一个能够匹配任意数量的正则表达式( )。
非常感谢获得正则表达式模式的任何帮助。提前谢谢。
答案 0 :(得分:1)
这不能在理论上完成,并且只有在预先知道最大数量的嵌套括号时才能在实践中完成。这个解决方案需要一个相当不愉快的表达,并且通常被尝试作为好奇的家庭作业。这里有一个link,可以更好地解释为什么regexp语言不足以解决匹配的括号问题。
你需要一个解析器来解决这个问题;一个简单的recursive descent就可以了。上面链接中的维基百科文章在C中有一个示例实现,您应该可以相对轻松地将其翻译成其他语言。
答案 1 :(得分:1)
使用纯正则表达式匹配任意数字是不可能的。换句话说,当您无法生成/编写正则表达式时,您无法匹配未知的计数。只要您在生成正则表达式时知道n
,就可以匹配n
对(无论多高n
)。
答案 2 :(得分:0)
记录下降解析可能是最好的选择。但是如果你只是想找到(S)平衡,可以使用在引擎中进行递归的正则表达式来完成。
它会找到最大的平衡点。如果您希望嵌套(S(S))可能涉及递归调用实现正则表达式的函数,则传递成功匹配的“核心”。并且可能在此过程中创建父子结构。但如果涉及到它,那么真正的解析器可能就是解决方案。
如何使用Perl正则表达式解决 -
$str = '(some (stuff (S (A (B (D xyz)) (C m))) the end ) (S extra))';
$regex = qr~
[(]
\s* S \s*
( # 1
( # 2
[(]
(?: (?> [^()]+ )
| (?2)
)*
[)]
)
|
[^)]*
)
[)]
~x;
while ($str =~ /$regex/g)
{
print "found '$1'\n";
}
打印
found '(A (B (D xyz)) (C m))'
found 'extra'