代码之家  ›  专栏  ›  技术社区  ›  Cristian Diaconescu

找到与Regex匹配的括号

  •  4
  • Cristian Diaconescu  · 技术社区  · 14 年前

    输入是表示元素列表的字符串。

    列表被定义为开放的卷发 { } .

    文本是一系列非空白字符。如果元素包含花括号,则必须用反斜杠转义: \{ \}

    例子:

    "{abc { def ghi } 7 { 1 {2} {3 4} } {5 6} x\{yz \}foo }"
    

    文本中没有卷曲:

    "{abc { def ghi } 7 { 1 {2} {3 4} } {5 6} xyz foo }"
    

    我想知道的是:是否可以使用regex将输入拆分为最外层循环的元素?

    预期产量:

    abc
    { def ghi }
    7
    { 1 {2} {3 4} }
    {5 6}
    x{yz
    }foo
    

    真正的问题是:这可以用正则表达式来完成吗?

    4 回复  |  直到 14 年前
        1
  •  3
  •   Kobi    14 年前

    好吧,这个编辑删除了标记中的花括号,并消除了问题中的刺痛,现在使用平衡组在.Net正则表达式中很容易实现。它只是匹配大括号,这是一个基本的例子。

    同样,这是更好地用于娱乐目的:

    (?:                    # try matching...
        (?:\\[{}]|[^\s{}])+\s*? # a literal (allow escaped curly braces)
        |                       # OR
        (?<Curly>{)\s*          # "{" and push to stack
        |                       # OR
        (?<-Curly>})\s*?        # "}", pop from stack and fail if the stack is empty
    )+?                    # ...a few times, and stop whenever you can.
    (?(Curly)(?!))         # Make sure there aren't any extra open curly braces
    

    有关更多详细信息,请参阅本文: Regex Balancing Group in Depth

        2
  •  4
  •   Community T.Woody    7 年前

    语法可以写成

    ELEMENT  -> (?!\{)\S+ | LIST
    LIST     -> '\{\s*' ELEMENT? ('\s+' ELEMENT)* '\s*\}' 
    

       \{\s*(?0)?(?:\s+(?0))*\s*\}|(?!\{)(?:[^\s}]|\}(?![\s}]))+
    
    #  ---------------------------                   ^^^^^^^^^
    #            LIST                    Make sure the } is not closing the group
    

    看到了吗 http://www.ideone.com/SnGsU { }

    (当然,不要在工作中尝试:))

    (顺便说一句,我不知道如何将这个PCRE转换成.NET风格。如果有人知道,请试一试 Converting PCRE recursive regex pattern to .NET balancing groups definition )

        3
  •  2
  •   Cristian Diaconescu    14 年前

    这里需要的是一个上下文无关的解析器,它的实现可以归结为一个有限状态机+一个堆栈。
    ANTLR , bison 等。

        4
  •  1
  •   Adam Matan    14 年前

    不过,解决方法更简单:只需保留一个开括号数的计数器,并确保它不会降到0以下。它比维护堆栈节省更多内存,而且您只需要括号的计数,而不需要括号的内容。

    算法:

    counter = 0                        // Number of open parens
    For char c in string:              
        print c                        
        if c=='{':                     // Keep track on number of open parens
            counter++
        if c=='}':
            counter--
        if counter==1:                 // New line if we're back to the top level
            print "\n"
        elif counter<1:                // Error if the nesting is malformed
            print "ERROR: parentheses mismatch"
            break