21

正規表現を使用して、左中括弧の数が右中括弧の数と等しいかどうかを確認する方法は?

コードは次のとおりです。

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

9 に答える 9

61
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()コードが間違っていると構文エラーが発生するため、これは機能します。エラーをキャッチするということは、エラーを安全に処理し、やりたいことを何でもできることを意味します。もう1つの良い点は、コードを実行せず、解析するだけであるということです。基本的に、あなたはあなたのタスクをブラウザのパーサーに活用しています。

正規表現は使用しませんが、コードが有効かどうかはチェックします。したがって、括弧が一致するかどうかがわかります。

于 2012-12-19T11:06:45.807 に答える
13

タスクは、正規表現なしで簡単に解決できます。中かっこを数えるだけです。

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');
于 2012-12-19T11:00:30.817 に答える
5

式が有効かどうかを確認することが目的の場合 (これは、ブラケットのみを含む部分文字列が正しいブラケット シーケンスを形成することも意味します)、regexps は役に立ちません。

正規表現は、いわゆる「正規言語」のみを処理できます (ただし、JS 正規表現は、理論上の同等のものよりもいくらか強力である可能性がありますが、そのような強力な代償はより複雑になります) 正しいブラケット シーケンスの言語は正規ではありません。

これらのスライドをご覧ください。正規表現が正しいブラケット シーケンスを認識できない理由を垣間見ることができます。

とはいえ、問題はそれほど難しいものではありません。スタックを維持し、文字列を左から右に移動するだけです。開始ブラケットに遭遇するたびに、それをスタックにプッシュします。閉じ括弧に遭遇すると、スタックの一番上の要素をポップし、そのタイプが自分のものと一致するかどうかを確認します (はい、このアルゴリズムは複数のタイプの括弧を処理できます)。最後に、スタックが空かどうかを確認する必要があります。

さまざまな種類のブラケットを処理する必要がない場合 (たとえば、'(' と ')' しかない場合) は、変数を維持するだけでopenBrackets(基本的にスタックのサイズを表す)、負にならないようにすることができます。 .

于 2012-12-19T11:31:33.767 に答える
4
if (expression1.match(/\(/g).length === expression2.match(/\)/g).length) {
    // is equal
}

中括弧を含まない文字列で機能させるには、次の回避策を使用できます。

((expression1.match(/\(/g) || []).length
于 2012-12-19T10:53:32.130 に答える
3

カウントだけが気になる場合は、このようなことを試してみませんか。

if(expression1.split('(').length == expression1.split(')').length) {
  alert('matched');
}
于 2012-12-19T11:00:14.623 に答える
3

これを行う別の方法は次のとおりです。

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;
}
于 2012-12-19T16:17:11.190 に答える
0
  1. 「正規表現を使用して、中括弧の数と中括弧の数を一致させる必要があります」

  2. 「有効な構文も確認する必要があります。」

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
于 2013-03-14T21:14:05.677 に答える
0

試す ...

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

...すると、アラートのコードは次のようになります...

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

作業コピー: jsFiddle

于 2014-12-17T05:11:56.480 に答える