我正在寻找一个可以转义单引号的JavaScript正则表达式,但它不应该转义已经转义的单引号。
答案 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