Подтвердить что ты не робот

Как проверить, равно ли количество открытых фигурных скобок количеству близких фигурных скобок?

Как проверить, равно ли количество открытых фигурных скобок, количество закрытых фигурных скобок, используя регулярные выражения?

Вот код:

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

Это 2 выражения, где в expression1 число открытых скобок равно числу закрытых скобок, а в expression2 число открытых скобок не равно числу закрытых скобок. Мне нужно регулярное выражение, которое подсчитывает количество открытых скобок и закрывает скобки и дает мне предупреждение. Мне также нужно проверить действительный синтаксис.

if(expression1.......){ // here goes the regular expression
    alert("Matched");
}
else{
    alert("Not matched");
}
4b9b3361

Ответ 1

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);
    }
}

Это работает, потому что new Function() приведет к синтаксической ошибке, если ваш код неверен. Улавливание ошибки означает, что вы можете справиться с этим безопасно и делать все, что захотите. Другое дело, что он не выполняет код, он просто разбирает его. В основном, вы используете свою задачу для анализатора браузера.

Он не использует регулярное выражение, но проверяет, действительно ли ваш код. Таким образом, он сообщает вам, соответствуют ли круглые скобки.

Ответ 2

Задача может быть просто решена без регулярного выражения, просто подсчитайте фигурные скобки.

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');

Ответ 3

Если ваша цель - проверить правильность выражения (это также означает, что подстрока, содержащая только скобки, формирует правильную последовательность скобок), то регулярные выражения вам не помогут.

Регулярные выражения могут обрабатывать так называемые " обычные языки" (хотя регулярные выражения JS могут быть несколько более мощными, чем их теоретические аналоги, цена таких мощность - большая сложность), а язык правильных последовательностей скобок не является регулярным.

Смотрите эти слайды - они могут дать вам представление о том, почему регулярные выражения не могут распознать правильную последовательность скобок.

Тем не менее, проблема не так сложна. Вы должны просто поддерживать стек и перебирать свою строку слева направо. Каждый раз, когда вы встречаете открывающий кронштейн, вы вставляете его в стек. Когда вы встретите закрывающую скобку, вы поместите верхний элемент стека и проверьте, соответствует ли его тип вашему (да, этот алгоритм может обрабатывать скобки нескольких типов). В конце вы должны просто проверить, пуст ли пуст.

Если вам не нужно обрабатывать разные типы скобок (например, у вас есть только "(" и "), вы можете просто сохранить переменную openBrackets (по существу, это будет представлять размер стека) и дон 'пусть он станет отрицательным.

Ответ 4

if (expression1.match(/\(/g).length === expression2.match(/\)/g).length) {
    // is equal
}

Чтобы заставить его работать со строками, не содержащими скобок, вы можете использовать следующее обходное решение:

((expression1.match(/\(/g) || []).length

Ответ 5

Вот еще один способ сделать это:

function validParenNesting(text) {
    var re = /\([^()]*\)/g; // Match innermost matching pair.
    // Strip out matching pairs from the inside out.
    while (text.match(re))
        text = text.replace(re, '');
    // If there are any parens left then no good
    if (text.match(/[()]/))
        return false;
    // Otherwise all parens part of matching pair.
    return true;
}

Ответ 6

Если вы только заботитесь о count, почему бы вам не попробовать что-то вроде этого.

if(expression1.split('(').length == expression1.split(')').length) {
  alert('matched');
}

Ответ 7

  • "Мне нужно сопоставить число открытых фигурных скобок, равное отсутствию близких фигурных скобок, с использованием регулярного выражения"

  • "Мне нужно также проверить действительный синтаксис".

Если значение 2 истинно, то верно и 1. Итак, найдите совпадения для того, что вы знаете, является допустимым синтаксисом - в этом случае: {}. Выполните цикл, который удаляет все допустимые совпадения из "стека", пока не будет допустимых совпадений. Если то, что осталось в конце, ничего, значит, ваш аргумент на 100% действителен. Если что-то осталось в конце - это означает, что "остатки" не прошли ваш тест на достоверность и, таким образом, недействительны:

var foo = function(str) {
    while(str.match(/{}/g))           // loop while matches of "{}" are found
        str = str.replace(/{}/g, ''); // "slices" matches out of the "stack"
    return !str.match(/({|})/g);      // `false` if invalids remain, otherwise `true`
};

foo('{{{}}}'); // true
foo('{{}}}}}}}}}}{}'); // false

Ответ 8

Попробуйте...

function matchBraces(s) {
  return s.match(/\(/g).length === s.match(/\)/g).length;
}

... тогда ваш код для предупреждений будет следующим:

if(matchBraces(expression1)) {
    alert("Matched");
} else {
   alert("Not matched");
}

Рабочая копия: jsFiddle

Ответ 9

Для нахождения числа скобок можно применить следующее. Однако он не использует RegExp и использует простую логику.

var l = 0;
var r = 0;
//Count the number of brackets.
for(var i=0;i<str.length;i++){
  if(str[i]=="("){
    l++;
  }
  else if(str[i]==")"){
    r++;
  }
}
if(l==r){ //The number of opening and closing brackets are equal.
  doSomething();
}