我需要解析以下形式的表达式:
(S (A (B (D xyz)) (C )
的数量(将始终等于的数量),但在(S )之间可以有任意数量的左括号和右括号对。在本例中,我想提取(A (B (D xyz)) (C ))。一个文件中可能有任意数量的(S )子句,所以我不能简单地执行^(S .* )$类型的模式匹配。
如果我知道(S )之间潜在的开始和结束括号对的数量,这就不难了,但是我不确定如何编写一个正则表达式来匹配任意数量的()。
在获得regexp模式方面的任何帮助都将不胜感激。提前谢谢。
发布于 2012-05-17 00:03:01
这在理论上是做不到的,而在实践中只有在预先知道最大嵌套括号数量的情况下才能做到。这种解决方案需要一个相当不愉快的表达,并且通常被尝试作为一个奇怪的家庭作业。下面是一个link,它更好地解释了为什么正则表达式语言不足以解决括号匹配问题。
您需要一个解析器来解决这个问题;一个简单的recursive descent解析器就可以解决这个问题。Wikipedia上的文章在上面的链接中有一个用C编写的示例实现,您应该能够相对容易地将其翻译成其他语言。
发布于 2012-05-17 00:06:02
使用纯正则表达式不可能匹配任意数字。换句话说,当您生成/编写正则表达式时,您不能匹配它是未知的计数是不可能的。匹配n对(不管n有多高)是可能的,只要您在生成正则表达式时知道n。
发布于 2012-05-17 02:54:00
也许记录下降解析将是最好的选择。但是如果你只是想要找到(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'https://stackoverflow.com/questions/10622302
复制相似问题