7

欠落している括弧を検出するために正規表現を使用することはできないと考えるのは正しいですか(ペアを数える方法がないため)?JavaScriptを使用して、約1,000個の文字列が切り捨てられ、手動で編集する必要があります。このリストを、コードを使用して注意が必要なリストに絞り込むことができるようにしたいと思っていました。文字列は次の形式で考えることができます。

  • (これは問題なく、注意を払う必要はありません)
  • これも【元気】
  • これは悪いです(そして編集する必要があります
  • これは(また)悪いです
  • これは}悪いです
  • この文字列には角かっこはありませんが、考慮する必要があります

これが不可能な場合は、ブラケットのペアを探す関数を作成する必要があります。ありがとうございました

4

4 に答える 4

10
function isFine(str) {  
  return /[(){}\[\]]/.test( str ) && 
    ( str.match( /\(/g ) || '' ).length == ( str.match( /\)/g ) || '' ).length &&
    ( str.match( /\[/g ) || '' ).length == ( str.match( /]/g ) || '' ).length &&
    ( str.match( /{/g ) || '' ).length == ( str.match( /}/g ) || '' ).length;
}

テスト

isFine('(this is fine and does not need attention)');                 // true
isFine('This is also [fine]');                                        // true
isFine('This is bad( and needs to be edited');                        // false
isFine('This [is (also) bad');                                        // false
isFine('as is this} bad');                                            // false
isFine('this string has no brackets but must also be considered');    // false

ただし、これは角かっこ順序をチェックしないことに注意してください。つまり、a)b(c問題ないと見なされます。

ちなみに、これは角かっこが欠落していないかどうかをチェックし、各タイプのバランスが正しく取れているかどうかをチェックする関数です。は許可されませんが、各タイプが個別にチェックされるa)b(cため、許可されます。(a[bc)d]

function checkBrackets( str ) {
    var lb, rb, li, ri,
        i = 0,
        brkts = [ '(', ')', '{', '}', '[', ']' ];   
    while ( lb = brkts[ i++ ], rb = brkts[ i++ ] ) { 
        li = ri = 0;
        while ( li = str.indexOf( lb, li ) + 1 ) {
            if ( ( ri = str.indexOf( rb, ri ) + 1 ) < li ) {
                return false;
            }
        }
        if ( str.indexOf( rb, ri ) + 1 ) {
            return false;
        } 
    }
    return true;
}

最後に、Christopheの投稿に加えて、欠落している角かっこをチェックし、すべてが正しくバランスが取れてネストされていることを確認するための最良の解決策は次のとおりです。

function checkBrackets( str ) {
    var s;
    str = str.replace( /[^{}[\]()]/g, '' );
    while ( s != str ) { 
        s = str;
        str = str.replace( /{}|\[]|\(\)/g, '' )
    }
    return !str;
};

checkBrackets( 'ab)cd(efg' );        // false   
checkBrackets( '((a)[{{b}}]c)' );    // true   
checkBrackets( 'ab[cd]efg' );        // true   
checkBrackets( 'a(b[c)d]e' );        // false   
于 2013-01-15T11:31:44.690 に答える
3

正規表現自体で再帰を実行することはできませんが、JavaScriptでいつでも実行できます。

次に例を示します。

// First remove non-brackets:
string=string.replace(/[^{}[\]()]/g,"");
// Then remove bracket pairs recursively
while (string!==oldstring) {
  oldstring=string;
  string=string.replace(/({}|\[\]|\(\))/g,"");
}

残りは不一致の括弧です。

ライブデモ: http: //jsfiddle.net/3Njzv/

ペアを数える必要がある場合は、一度に1つずつ交換を行い、カウンターを追加できます。

// First remove non-brackets:
string=string.replace(/[^{}[\]()]/g,"");

// Then remove bracket pairs recursively
var counter=-1;
while (string!==oldstring) {
  counter ++;
  oldstring=string;
  string=string.replace(/({}|\[\]|\(\))/,"");
}
于 2013-01-16T22:47:25.697 に答える
2

再帰的な正規表現を使用して、一致する括弧を確認することができます。たとえば、Perlでは、次の式は適切な() {} []ネストを持つ文字列と一致します。

$r = qr/(?:(?>[^(){}\[\]]+)|\((??{$r})\)|\{(??{$r})\}|\[(??{$r})\])*/;

わかりやすくするために、同じ式を展開します。

$r = qr/
    (?:
        (?>
            [^(){}\[\]]+
        )
    |
        \(
            (??{$r})
        \)
    |
        \{
            (??{$r})
        \}
    |
        \[
            (??{$r})
        \]
    )*
/x;

*外側のグループは、空の文字列と一致する代わりにで定量化さ+れるため、$r有用にするために、実際の一致は、先読み/後読みを利用するか、コンテキストを確立する式を使用して実行する必要があります/^$r$/。たとえば、次の例では、適切なネストがないファイル内の行のみが出力されます。

perl -ne '$r = qr/(?:(?>[^(){}\[\]]+)|\((??{$r})\)|\{(??{$r})\}|\[(??{$r})\])*/; print if !m/^$r$/' file

明確化に対処するには:これらがファイル名であり、ファイルの内容ではない場合は、上記のコマンドの出力lsまたはその他をパイプでつなぐことができます。findfile

ls | perl -ne '$r = qr/(?:(?>[^(){}\[\]]+)|\((??{$r})\)|\{(??{$r})\}|\[(??{$r})\])*/; print if !m/^$r$/'

ただし、他の人が言っているように、一般的には非正規表現のソリューションの方がおそらく優れています。

注意: Perlドキュメントから: "警告:この拡張正規表現機能は実験的なものと見なされ、予告なしに変更される場合があります。副作用のある実行されたコードは、regexエンジンの将来の最適化の影響により、バージョンごとに同じように実行されない場合があります。 。」

于 2013-01-15T10:24:24.613 に答える
1

一部の正規表現フレーバーは、ネストされた括弧などの再帰構造に一致させることができますが、構文は非常に複雑であるため、通常、関数を作成するだけの方が簡単です。JavaScript正規表現は、再帰をまったくサポートしていません。

于 2013-01-15T09:58:38.437 に答える