开发者

How do you safely wrap a JS string variable in double quote chars?

开发者 https://www.devze.com 2022-12-22 02:18 出处:网络
Obviously when you\'re creating an actual string literal yourself,you backslash escape the double quote characters yourself.

Obviously when you're creating an actual string literal yourself, you backslash escape the double quote characters yourself.

var foo = "baz\"bat";

Just as you would with the handful of other control characters, like linebreaks and backslashes.

var bar = "baz\\bat\nmynew line and a \"quote\" ";

but if you're just wrapping that existing variable in quote character, ie to give it to some other system that requ开发者_高级运维ires quoted input, there's some confusion.

Obviously you have to escape any potential double quote characters that are in the string.

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

But according to some you also now have to worry about escaping literal backslash characters in the variable. In other words using much bigger hammer than my little regex. However i dont see why.


You might want to avoid escaping quotes you already escaped-

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


The answer is that yes, you have to do two things:

  1. replace literal backslash characters in the string, with two backslashes,
  2. THEN, you proceed replacing any occurrences of " with \".

the simplest explanation for why step 1 is essential, is to consider the 5-character string :

foo\"   

After the first 3 characters (foo), there is a literal backslash character in the string, and then there is a literal double quote character.

(Put another way, as a string literal this would look like "foo\"")

If I were to only replace the quote character, i'd end up with a quoted string whose value was

foo\\"     

But the two backslashes here will be interpreted as a single backslash. So when I wrap this value in quotes, I end up with unbalanced quotes.

"foo\\""

on the other hand, if I do step 1 first -- replacing all backslashes with double backslashes gives

foo\\"

and then step 2 -- replacing the quote with slash-quote gives

foo\\\"

Now when i wrap my value in quote characters i finally get

"foo\\\""

which is correct.


There is a non standard str.quote() in FF

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/quote They suggest the following 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);
}


You might want to escape other characters aside from quotes, eg whitespace characters (newlines!) and/or non-ASCII characters. There's Crockford's quote(), and my own implementation can be found at mercurial.intuxication.org.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号