찾다

 >  Q&A  >  본문

请问正则如何匹配多层成对的括号?

"()" => returns true
")(()))" => returns false
"(" => returns false
"(())((()())())" => returns true

形如这种,我可以做到匹配2,3层的没问题,但是层数多了就不知道该怎么办了


高洛峰高洛峰3030일 전958

모든 응답(2)나는 대답할 것이다

  • 三叔

    三叔2016-11-11 13:03:57

    这种括号匹配必须要求正则支持嵌套或者递归阿之类的东西

    我有个简单的想法,就是用正则把所有匹配的括号都替换掉。。。

    下面是用perl6 实现的,如果看不懂理解一下想法就好了。。。

    #!/usr/bin/env perl6
     
    use v6;
     
    my \stdin = $*IN;
     
    my Int $count = +stdin.get();
     
    for ^$count {
        my Str $str = stdin.get();
     
        while $str.chars > 0 {
            last unless $str ~~ s:g/[ \[ \] || \( \) ]+//; ## 去掉所有匹配的括号
        }
     
        say $str.chars ?? "No" !! "Yes"; ##如果 还存在不能去除的字符,说明匹配失败 。。
    }

    嵌套是这样子的。。

    #!/usr/bin/env perl6
    
    grammar Bracket { ## 语法类型  *匹配0或以上 +匹配1或以上
        rule TOP {
            * 
        }
        token pair { # 匹配 
     或者 是 +
            
     |         +
        }     token bl {         <[ \( \[ ]> # 匹配 '(' 或者  '['     }     token br {         <[ \) \] ]> # 匹配 ')' 或者 ']'     } } ## 测试语句 匹配上就打印匹配得到的语法树 匹配不到就是Nil say Bracket.parse("()"); say Bracket.parse('(()'); say Bracket.parse("(((((())))))"); say Bracket.parse("((()))((()))");

    最后贴个图

    bVFkzX.png

    회신하다
    0
  • 欧阳克

    欧阳克2016-11-11 13:03:03

    维护一个计数器,如果是左括号加1,右括号减一,最后判断计数器是否等于0。

    function match(str) {
        var n = 0;
        for (s of str) {
            if (s === '(') {
                n++;
            } 
            if (s === ')') {
                if (n === 0) {
                    return false;
                }
                n--;
            }
        }
        return n === 0;
    }


    회신하다
    0
  • 취소회신하다