如何检查开括号的数量是否等于闭括号的数量?

mad*_*dhu 21 javascript regex

如何检查开括号的数量是否等于使用正则表达式的闭括号数?

这是代码:

var expression1 = "count(machineId)+count(toolId)";
var expression2 = "count(machineId)+count(toolId))";
Run Code Online (Sandbox Code Playgroud)

这些是2个表达式,其中expression1,开括号的数量等于近括号expression2的数量,并且,开括号的数量不等于近括号的数量.我需要一个正则表达式来计算开括号和小括号的数量,并给我提醒.我也需要检查有效的语法.

if(expression1.......){ // here goes the regular expression
    alert("Matched");
}
else{
    alert("Not matched");
}
Run Code Online (Sandbox Code Playgroud)

Flo*_*ine 60

var expression1 = "count(machineId)+count(toolId)";
var expression2 = "count(machineId)+count(toolId))";

if (matches(expression1)) {
    alert("Matched"); // Triggered!
}
else {
    alert("Not matched");
}

if (matches(expression2)) {
    alert("Matched");
}
else {
    alert("Not matched"); // Triggered!
}

function matches(str) {
    try {
        new Function(str);
        return true;
    }
    catch (e) {
        return !(e instanceof SyntaxError);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为new Function()如果您的代码错误将导致语法错误.捕获错误意味着您可以安全地处理它并做任何您想做的事情.另一个好处是它不执行代码,它只是解析它.基本上,您正在将您的任务用于浏览器的解析器.

它不使用正则表达式,但会检查您的代码是否有效.因此,它会告诉您括号是否匹配.

  • 没有言语.那很完美.+100. (12认同)
  • 如果你关心的是括号是否都匹配,那么不要使用这个解决方案.假设所有括号都匹配,但其中的表达式不是有效代码.在这种情况下,将抛出异常,并且您将得到错误的结果.这是一个完全不同的问题的正确答案; 但这个错误的答案. (10认同)
  • 您可以使用O(n)循环轻松实现此功能.使用函数构造函数来简单地进行解析要贵得多.检查匹配的括号只需要编译器的前两个阶段(扫描程序和解析器).虽然该实现是在C/C++中,但在处理大N时,它不可能比O(n)快. (6认同)

Dam*_*ask 12

任务可以简单地解决而无需正则表达式,只需计算括号.

var a = 'count(machineId)+count())toolId)'
var braces = 0;
for (var i=0, len=a.length; i<len; ++i) {
   switch(a[i]) {
       case '(' : 
          ++braces;
          break;
       case ')' : 
           --braces;
           break;
   }
   if (braces < 0) {    
      alert('error');
      break;
   }
}

if (braces)
    alert('error');
Run Code Online (Sandbox Code Playgroud)


Art*_*lev 5

如果您的目标是检查表达式是否有效(这也意味着它的子字符串只包含括号形成正确的括号序列),那么正则表达式将无法帮助您.

正则表达式只能处理所谓的" 常规语言 "(虽然JS regexps可能比它们的理论对应物更强大,但这种权力的代价更复杂),而正确括号序列的语言不规则.

查看这些幻灯片 - 它们可以让您了解正则表达式无法识别正确的括号序列的原因.

然而,问题并不那么难.你应该只保持一个堆栈并从左到右翻过你的字符串.每当你遇到一个开口支架,你就把它推到堆叠上.当你遇到一个结束括号时,你弹出堆栈的顶部元素并检查它的类型是否与你的类型匹配(是的,这个算法可以处理多种类型的括号).最后,您应该检查堆栈是否为空.

如果您不需要处理不同类型的括号(例如,您只有'('和')'),您可以只维护一个变量openBrackets(基本上它代表堆栈的大小)并且不要让它变为负数.