正则expression式匹配

我想写一个正则expression式匹配之间的任何东西

() (()) (()()) ((())) ()()() 

等等

所有这些答案声称你不能使用模式匹配一​​个string与平衡嵌套parens是相当错误的。 假设现代编程语言所匹配的模式在病理学教科书意义上被限制为“正规语言”是不现实的。 只要你允许反向引用,他们就不会。 这使得真实世界的模式比教科书版本更加匹配,使得它们更加实用。

匹配平衡零件的最简单模式是\((?:[^()]*+|(?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 

命名你的抽象也有很多要说的,并且把它们的定义和它的sorting从执行中分离出来。 这导致了这样的事情:

 my $nested_paren_rx = qr{ (?&nested_parens) (?(DEFINE) (?<open> \( ) (?<close> \) ) (?<nonparens> [^()] ) (?<nested_parens> (?&open) (?: (?&nonparens) *+ | (?&nested_parens) ) * (?&close) ) ) }x; 

第二种forms现在可以包含在更大的模式中。

永远不要让任何人告诉你不能使用模式来匹配recursion定义的东西。 正如我刚才所展示的,你当然可以。

当你在这个时候,确保不要写行噪声模式。 你不必,也不应该。 禁止使用禁止空格,注释,子例程或字母数字标识符的编程语言。 所以在你的模式中使用所有这些东西。

当然,这样对于为这种工作select正确的语言确实有帮助。 ☺

如果您遇到正则expression式语法不支持recursion匹配的语言,我会给您一个简单的Javascript实现,您可以根据自己的select使用自己的语言:

 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/

正则expression式无法有效处理这样的嵌套结构。 你需要的是这个语法的语法和parsing器。 在你的情况下,语法很简单。 如果您正在使用python尝试pyparsing或funcparserlib。

用pyparsing你可以做到以下几点:

 from pyparsing import nestedExpr nestedExpr().parseString( "(some (string you) (want) (to) test)" ).asList() 

这将返回一个包含嵌套stringparsing组件的列表。 nestedExpr的默认分隔符是括号,所以你不必做任何额外的事情。 如果你想使用funcpasrerlib你可以尝试以下

 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))" ) 

它将返回元组中的parsing元素。

祝你好运。 你需要一个有限状态自动机和一个堆栈来parsing这样的事情。 它不能使用正则expression式分析,因为它不够强大。