Как проверить, равно ли количество открытых фигурных скобок количеству близких фигурных скобок?
Как проверить, равно ли количество открытых фигурных скобок, количество закрытых фигурных скобок, используя регулярные выражения?
Вот код:
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");
}
Ответы
Ответ 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();
}