【问题标题】:Javascript do not match str surrounded with quotesJavascript 不匹配用引号括起来的 str
【发布时间】:2011-10-01 04:43:42
【问题描述】:

我正在 javascript 中编写一个正则表达式,它在以下情况下替换空格 except

  1. 一些特定的语法是在前面的空白
  2. 它被单引号和双引号括起来(引号内的转义引号除外)

现在,我有很大一部分工作要做。它匹配所有在空格前面没有特定语法的模式,但是,我坚持使用引号部分。

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

我已经做了很多测试,但我就是想不通。提前致谢。

【问题讨论】:

  • 我很惊讶它到目前为止仍然有效。我希望您必须将关键字放在大括号中。即 ((function)|(new)|(return)|(var))。
  • 请注意,这种简单的解析在一般情况下是行不通的。例如,即使您让简单的引用起作用,它仍然会在 cmets、正则表达式引用等上中断。
  • 这对“被引号包围”的问题有帮助吗? stackoverflow.com/questions/366202/…
  • @phtrivier,它是 Java(JS 没有后向功能),并且(大部分)答案不处理转义。
  • 如果您提供示例文本以及所需的匹配项,我相信,我们会找到一个模式。

标签: javascript regex replace quotes lookbehind


【解决方案1】:

你可以使用:

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 的好方法,并且会在 cmets、正则表达式引用以及其他情况下中断。

注意2:忘记补充了,这仅适用于“有效”引用,所有引用必须关闭。

【讨论】:

  • 为这样的正则表达式魔法喝彩!但它还不是相当。此正则表达式假定所有引号都已关闭(例如,如果 str = "x ' asdf " (jsfiddle.net/uAcse) 则失败)。所有需要发生的只是另一个测试,首先查看字符串是否包含正确的引号。如果没有,那么....我不知道该怎么做
  • 谢谢。 :-) 是的,它只适用于有效的 JS(单行引号),忘了说。 (不知道有没有办法在JS中做多行引号,如果有的话也不行。)
  • 如前所述,您非常接近。我感谢您的时间和您出色的正则表达式魔术。它几乎解决了我的问题,但没关系。肯定会投票。我不敢相信 JS 不支持lookbehinds :/
【解决方案2】:

我的建议:

  • mimic lookbehind 在 javascript 中(尽管这个 hack 可能并不完美)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-11
    • 2010-09-12
    • 2018-01-30
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多