如何安全地在JS字符串变量中添加双引号字符?

3
显然,当您自己创建实际的字符串文字时,您需要自己反斜杠转义双引号字符。
var foo = "baz\"bat";

就像您处理其他控制字符一样,例如换行符和反斜杠。
var bar = "baz\\bat\nmynew line and a \"quote\" ";

但是,如果你只是在现有变量中加引号,例如为了将其提供给某些需要引号输入的系统,那么就会存在一些混淆。

显然,您必须转义任何可能在字符串中出现的双引号字符。

var doubleQuoteRe = /\"/g;
var quoted = "\"" + unquoted.replace(escaper, '\\\"') + "\"";

但是,据一些人称,您现在还必须担心在变量中转义字面反斜杠字符。换句话说,这比我使用的小正则表达式更加繁琐。然而,我不明白为什么要这样做。


为什么这个不能工作?var s1 = "a\"b"; var s2 = "\"" + s1 + "\""; - Chris Farmer
2
当你说“你已经一个变量”时,你是什么意思?你在哪里有这个变量,你需要用它做什么?这个问题对我来说没有意义。 - Pointy
谢谢 - 是的,我最后表述的方式相当令人困惑。我已经更新了问题。 - nmealy
4个回答

3

您可能希望避免转义已经转义过的引号 -

String.prototype.inquotes=function(){
 return '"'+this.replace(/(^|[^\\])"/g,'$1\\"')+'"';
}

1
答案是:是的,您需要执行两个步骤:
  1. 将字符串中的反斜杠替换为两个反斜杠,
  2. 然后,再将任何出现的 " 替换为 \"。

为什么第一步很重要的最简单解释就是考虑这个五个字符的字符串:

foo\"   

在前三个字符(foo)之后,字符串中有一个字面上的反斜杠字符,然后是一个字面上的双引号字符。

(换句话说,作为字符串文字,它看起来像“foo \””)

如果我只替换引号字符,那么我最终会得到一个带引号的字符串,其值为

foo\\"     

但是这里的两个反斜杠将被解释为一个反斜杠。因此,当我将这个值用引号括起来时,就会出现不平衡的引号。

"foo\\""

另一方面,如果我先执行步骤1——将所有反斜杠替换为双反斜杠,则会得到:

foo\\"

然后第二步--用反斜杠引号替换引号,得到

foo\\\"

现在当我用引号字符包装我的值时,最终得到的结果是

"foo\\\""

这是正确的。


1

在火狐浏览器中存在非标准的str.quote()方法。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/quote他们建议使用以下polyfill(代码填充)

    if(!String.prototype.quote){
  // oop version - no dependencies
  String.prototype.quote = (function(){
    // prepare fallback
    // ----------------
    // backslash escape double quotes and backslashes
    var escp_regex = /[\\"]/g,
      escp_callback = '\\$&',
      // escape control characters
      ctrl_map = {
        '\b': '\\b', // backspace
        '\t': '\\t', // tab
        '\n': '\\n', // new line
        '\f': '\\f', // form feed
        '\r': '\\r'  // carriage return
      },
      // don't rely on `Object.keys(ctrl_map).join('')`
      ctrl_regex = new RegExp('[\b\t\n\f\r]', 'g'),
      ctrl_callback = function(match){
        return ctrl_map[match];
      },
      // hex-escape, spare out control characters and ASCII printables
      // [0-7,11,14-31,127-255]
      xhex_regex = /[\x00-\x07\x0B\x0E-\x1F\x7F-\xFF]/g,
      xhex_callback = function(match, char_code){
        char_code = match.charCodeAt(0);
        return '\\x' + (char_code < 16 ? '0' : '') + char_code;
      },
      // hex-escape all others
      uhex_regex = /[\u0100-\uFFFF]/g,
      uhex_callback = function(match, char_code){
        char_code = match.charCodeAt(0);
        return '\\u' + (char_code < 4096 ? '0' : '') + char_code;
      },
      // delegate to native `JSON.stringify` if available
      stringify = typeof JSON !== 'undefined' && JSON.stringify;

    // return actual polyfill
    // ----------------------
    return function(){
      var self = this; // promote compression
      if(self == null) throw new TypeError('can\'t convert ' + self + ' to object');
      if(stringify) return stringify(self);
      return '"' + self
        .replace(escp_regex, escp_callback)
        .replace(ctrl_regex, ctrl_callback)
        .replace(xhex_regex, xhex_callback)
        .replace(uhex_regex, uhex_callback) + '"';
    }
  }());

  // generic version - requires Function#bind
  String.quote = Function.call.bind(''.quote);
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接