1

次の場合を除いて、空白を置き換えるJavaScriptで正規表現を書いています。

  1. いくつかの特定の構文が空白の前にあります
  2. 一重引用符と二重引用符の両方で囲まれています(引用符内のエスケープされた引用符は除外されます)

今、私は大部分が働いています。空白の前に特定の構文がないすべてのパターンに一致しますが、引用部分にこだわっています。

return str.replace(/(function|new|return|var)?\s/g, function($0, $1) {
    return $1 ? $0 : '';
});

私はかなりのテストを行いましたが、それを理解することはできません。前もって感謝します。

4

2 に答える 2

2

以下を使用できます。

var str = "foo  \"b a \\\" r\" new y 'l o l' foo lol; var x = new 'fo \\' o' ";

var result = str.replace(/(function|new|return|var)?\s+(?=(?:[^\\"']|\\.)*(?:(?:"(?:[^\\"]|\\.)*"|'(?:[^\\']|\\.)*'))*(?:[^\\"']|\\.)*$)/gm,
function($0, $1) { return $1 ? $0 : ''; });

http://jsfiddle.net/qCeC4/を参照してください

/xPerl形式の先読み部分:

s/
\s+
(?=
    (?:[^\\"']|\\.)*
    (?:
        (?:
            "(?:[^\\"]|\\.)*"
            |
            '(?:[^\\']|\\.)*'
        )
    )*
    (?:[^\\"']|\\.)*$
)
//xmg;

注:前に述べたように、これは JS を解析するための良い方法ではなく、コメント、正規表現の引用、および他に何を知っているかで壊れます。

注 2:これは「有効な」引用符でのみ機能することを追加するのを忘れていました。すべての引用符を閉じる必要があります。

于 2011-07-08T12:25:38.923 に答える
1

私の提案:

  • javascript で後読みを模倣します (ただし、このハックは完全ではない可能性があります)。

  • 再帰降下パーサー (おそらく antlr) を使用しますか?

  • または、手動でコードを記述してそれを実行します。以下は、私が考えているものの最初のドラフトバージョンです (まだいくつかの疑似コードがあります):


function go(str) {
    var quoteStart, quoteEnd, quotedRanges, from, retval;
    quotedRanges = []; //quotedRanges holds the indexes inclusively within which nothing should be changed because it's quoted.


    quoteStart = str.indexOf('"');

    if( quoteStart > -1 ) {
        from = quoteStart;
        while (from !== false) {
            quoteEnd = str.indexOf('"', from);

            if (quoteEnd == -1) { //There is an unmatched quote. We pretend that it is closed off at the end of the string.
                quoteEnd = str.len;
                from = false;
            } else if(str.charAt(quoteEnd - 1) == "\\") {
                from = quoteEnd;
            } else { //we found the ending quote index.
                from = false;
            }
        }
        quotedRanges.push([quoteStart, quoteEnd]);
    }


    retval = str.replace(/(function|new|return|var)?\s/g, function($0, $statement) {
        if($0 within on of quotedRanges)
            return $0;
        return $statement ? $0 : '';
    });
    return retval;
}

assert(1, go("") == "");
assert(2, go("function ") == "function ");
assert(3, go(" ") == "");
assert(4, go('" "') == '" "');
assert(5, go('" ') == '" ');
assert(6, go('"x x"') == '"x x"');
assert(6, go('"new x"') == '"new x"');
assert(7, go(' "x x"') == '"x x"');
assert(8, go("' '") == "' '");
assert(9, go("' \\' '") == "' \\' '");


function assert(num, statement) {
    if(!statement) {
        document.write('test #' + num + ' failed! <br/>');
    }
}
于 2011-07-08T12:43:21.440 に答える