Javascript正则表达式来逃避引用(但没有逃脱已经转义的引号)

时间:2012-01-16 00:04:01

标签: javascript regex

我正在寻找一个可以转义单引号的JavaScript正则表达式,但它不应该转义已经转义的单引号。

4 个答案:

答案 0 :(得分:14)

理想情况下,您希望每场比赛都准确地从上一场比赛结束的地方开始。否则,很容易与转义序列失去同步。 @outis的正则表达式接近,但它无法逃脱'\\'中的第二个单引号。在第一场比赛之后,它必须匹配至少一个非反斜杠和一个单引号,这是它无法做到的。如果还有更多字符,它会向前跳过并在第二个单引号后开始匹配。

试试这个:

result = subject.replace(/([^'\\]*(?:\\.[^'\\]*)*)'/g, "$1\\'");

这是Friedl的“展开循环”模式的一个例子:

normal * (special normal *) *

[^'\\]*是“正常*”部​​分;除了单引号或反斜杠之外,它还会吞噬任意数量的字符。如果下一个字符是反斜杠,\\.(“特殊”)将消耗该字符,下一个字符(反斜杠,单引号或其他)和[^'\\]*将再次接管。根据需要重复。

关键是正则表达式永远不会向前跳过,它永远不会回溯。如果它看到反斜杠,始终会消耗该字符和下一个字符,因此它永远不会失去同步。

答案 1 :(得分:4)

如果存在偶数个反斜杠,则它们仅相互引用。因此,如果字符具有奇数个前面的反斜杠,则引用该字符。由于JS不支持lookbehind,因此您需要捕获前导的非反斜杠并将其包含在替换中。

var escquote = /((^|[^\\])(\\\\)*)'/g
"a ' b \' c \\' d".replace(escquote, "$1\\'")

但是,如果这是出于任何安全目的,出于多种原因,这是错误的方法。首先,如果你正在做这个客户端,那就不安全了。其次,当使用子系统提供的方法将数据发送到子系统时,应该处理引用。例如,如果数据要转到关系数据库,则应使用预准备语句并参数化不同的数据。准备好的语句参数不是注入漏洞。

答案 2 :(得分:3)

你可以写:

var escaped = original.replace(/\\['\\]|'/g, function (s) {
    if (s == "'") return "\\'";
    else return s;
});

如果有一个连续的转义逃逸序列,它会全部跳过它们。如果最后有一个“\”,那么引用已经被转义并且也被跳过。如果最后有一个“'”,报价就会被转义。

答案 3 :(得分:-1)

这是一个解决方案

/[^\\]\'|^\'/g