我希望编写一个正则表达式,可以匹配任何在
()
(())
(()())
((()))
()()()
etc.
我希望编写一个正则表达式,可以匹配任何在
()
(())
(()())
((()))
()()()
etc.
\((?:[^()]*+|(?0))*\)
。 但你应该永远不要写成这样,因为它过于紧凑,很难读懂。你应该总是使用/x
模式,以允许空格和注释。所以像这样写:m{
\( # literal open paren
(?: # begin alternation group
[^()]*+ # match nonparens possessively
| # or else
(?0) # recursively match entire pattern
)* # repeat alternation group
\) # literal close paren
}x
给你的抽象概念命名并将其定义与顺序与执行解耦开来也有很多好处,这会导致以下这种情况:
my $nested_paren_rx = qr{
(?&nested_parens)
(?(DEFINE)
(?<open> \( )
(?<close> \) )
(?<nonparens> [^()] )
(?<nested_parens>
(?&open)
(?:
(?&nonparens) *+
|
(?&nested_parens)
) *
(?&close)
)
)
}x;
第二种形式现在可以方便地包含在更大的模式中。
不要让任何人告诉你不能使用模式来匹配递归定义的内容。正如我刚刚演示的,你当然可以这样做。
顺便说一下,请确保永远不要编写看起来像噪声的模式。你不需要这样做,也不应该这样做。任何禁止使用空格、注释、子程序或字母数字标识符的编程语言都无法维护。因此,在您的模式中使用所有这些东西。
当然,选择正确的语言对于这种工作是有帮助的。☺
(.)\1
只是 aa|bb|cc|dd|...
的简写,您可以对所有使用回溯引用的情况进行相同的转换。实际上,[...]
表示法和 ?
表示法都只是经典正则表达式中的选择的简写。另一方面,递归正则表达式是一种非常不同的问题,使用该特性会使其不规则... - tobyodavies(.+).*\1
。这需要比自动机状态所需的辅助存储更多的存储空间,实际上它需要与匹配的输入字符串长度成比例的存储空间。这显然违反了ʀᴇɢᴜʟᴀʀ语言的基本属性之一,因此不能通过DFA解决,因为不能要求进一步的存储,特别是不能要求与输入长度成比例的存储。因此,该模式描述的语言根据定义不是ʀᴇɢᴜʟᴀʀ。 - tchristS ::= '(' S ')'
。我很想看看是否有人已经写了一篇关于正则表达式可以解析哪类语言的分析文章...(我仍然不认为递归正则表达式是一个“正常”的特性...我真的没有看到它们在这篇文章之外被使用过) - tobyodavies如果你遇到了不支持递归匹配的正则表达式语法,我会给你提供一个简单的Javascript实现,你可以根据自己选择的语言进行编写:
function testBraces(s) {
for (var i=0, j=0; i<s.length && j>=0; i++)
switch(s.charAt(i)) {
case '(': { j++ ; break; }
case ')': { j-- ; break; }
}
return j == 0;
}
在这里,您可以与它互动:http://jsfiddle.net/BFsn2/
(提示:此链接可供使用)j
不应该降到零以下,因为它表示不平衡。 - Marko Dumic&& j>=0
这一部分(它一直在那里还是你在五分钟内进行了编辑?)。太好了。 - Tim Pietzcker这样的嵌套结构无法有效地通过正则表达式处理。您需要的是语法和该语法的解析器。在您的情况下,语法足够简单。如果您正在使用Python,请尝试使用pyparsing或funcparserlib。
使用pyparsing,您可以执行以下操作:
from pyparsing import nestedExpr
nestedExpr().parseString( "(some (string you) (want) (to) test)" ).asList()
from funcparserlib.parser import forward_decl, many, a
bracketed = forward_decl()
bracketed.define(a('(') + many(bracketed) + a(')'))
bracketed.parse( "( (some) ((test) (string) (you) (want)) (to test))" )
祝你好运。你需要一个带有堆栈的有限状态自动机来解析这样的内容。它不能仅使用正则表达式进行解析,因为它不够强大。