正则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式分析,因为它不够强大。