搜索

首页  >  问答  >  正文

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

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

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

全部回复(15)我来回复

  • 黄舟

    黄舟2017-04-11 12:59:31

    不能。

    因为多层嵌套的括号是上下文无关文法,正则表达式只能匹配正则语言。

    这个恰好不属于正则语言,可以证明。

    回复
    0
  • 迷茫

    迷茫2017-04-11 12:59:31

    正则是会一点,但是看这个估计很难实现吧,实际上解决问题就可以了,不一定要用正则的,下面这种方法肯定可以,希望楼主采纳。
    思路:用0+0的方式填充括号里面的内容,最后用eval执行,如果执行成功则左右括号是一对一,否则失败。

            var abc = "(())((()())())";
            var a = abc.replace(/\)/g,"+)").replace(/\)\(/g,")+(").replace(/\(\+/g,"(0+").replace(/\+\)/g,"+0)");
            var flag;
            try{
                var b = eval(a);
                flag = true;
            }catch (e){
                flag = false;
            }
            console.log(flag);

    回复
    0
  • 阿神

    阿神2017-04-11 12:59:31

    这个,正则太麻烦,循环替换 '()' 不就好了?

    function checkKuohao(str){
        return str.indexOf('()') > -1 
            ? checkKuohao( str.replace('()', '') )
            : str === '';
    }

    如果括号中间可能有其他字符串的,可以修改一下上面的 replace 第一个参数,匹配一个括号就方便了嘛。

    回复
    0
  • PHP中文网

    PHP中文网2017-04-11 12:59:31

    PHP里可以使用递归实现。

    正则:$pattern = '#^((?:((?:(?1)|)))+)$#m';

    在线测试例子:
    https://regex101.com/r/hP0wV8/2

    回复
    0
  • 黄舟

    黄舟2017-04-11 12:59:31

    尝试用Java写了下,自己都不满意。

    public class Parentheses {
    
        public static void main(String[] args) {
            Parentheses p = new Parentheses();
            String str1 = "()"; // => returns true
            String str2 = ")(()))"; // => returns false
            String str3 = "("; // => returns false
            String str4 = "(())((()())())"; // => returns true
            System.out.println(p.test(str1));
            System.out.println(p.test(str2));
            System.out.println(p.test(str3));
            System.out.println(p.test(str4));
        }
        public boolean test(String str) {
            Stack<String> stack = new Stack<String>();
            boolean pauseAtMiddle = false;
            for (int i = 0; i < str.length(); i++) {
                char ch = str.charAt(i);
                if(')' == ch) {
                    if (stack.isEmpty()) {
                        pauseAtMiddle = true;
                        break;
                    }
                    stack.pop();
                } else if ('(' == ch) {
                    stack.push(String.valueOf(ch));
                } else {
                    System.out.println("not equal");
                    continue;
                }
            }
            if(pauseAtMiddle || !stack.isEmpty()) {
                return false;
            }
            return true;
        }
    }
    

    回复
    0
  • 取消回复