正则表达式匹配

时间:2010-10-27 08:09:03

标签: regex

我想编写一个匹配

之间的正则表达式
()
(())
(()())
((()))
()()()

4 个答案:

答案 0 :(得分:21)

所有这些答案声称你不能使用模式来匹配具有平衡嵌套parens的字符串是非常错误的。假装现代编程语言匹配的模式仅限于病理教科书意义上的“常规语言”是不切实际的。一旦你允许反向引用,它们就不会。这使得真实世界的模式比教科书版本更匹配,使它们更加实用。

匹配平衡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

对于命名抽象,并将其定义及其排序与执行分离,还有很多要说的。这导致了这种情况:

my $nested_paren_rx = qr{

    (?&nested_parens)

    (?(DEFINE)

        (?<open>       \(       )
        (?<close>       \)      )
        (?<nonparens> [^()]     )

        (?<nested_parens>
            (?&open)
            (?:
                (?&nonparens) *+
              |
                (?&nested_parens)
            ) *
            (?&close)
        )

    )
}x;

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

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

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

当然,它 帮助为这种工作选择正确的语言。 ☺

答案 1 :(得分:5)

如果您遇到正则表达式语法不支持递归匹配的语言,我会给您简单的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/

答案 2 :(得分:4)

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

通过pyparsing,您可以执行以下操作:

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

这将返回一个包含嵌套字符串的已解析组件的列表。 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))" )

它将返回元组中已解析的元素。

答案 3 :(得分:0)

祝你好运。祝你好运。你需要一个带有堆栈的有限状态自动机来解析这样的东西。它不能仅使用正则表达式进行解析,因为它不够强大。