Javascript与引号括起的str不匹配

时间:2011-07-08 10:58:20

标签: javascript regex replace quotes lookbehind

我正在 javascript 中编写一个正则表达式,用于替换时的空格:

  1. 某些特定语法是空白
  2. 前面的
  3. 它被单引号包围为双引号(不包括引号中的转义引号)
  4. 现在,我有很大的工作要做。它匹配所有在空白面前没有特定语法的模式,但是,我坚持使用引用部分。

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

    我做了很多测试,但我无法弄明白。提前谢谢。

2 个答案:

答案 0 :(得分: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/

Perl /x形式的前瞻部分:

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

注意:正如我之前所说的,这不是一个解析JS的好方法,会打破评论,正则报价引用,以及谁知道还有什么。

注意2:忘记添加,这仅适用于“有效”引用,所有引号必须关闭。

答案 1 :(得分:1)

我的建议:

    javascript中的
  • mimic lookbehind(虽然这个黑客可能并不完美)。

  • 使用递归下降解析器(也许是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/>');
    }
}