27

我通过接受 JSON 作为字符串的脚本(不是我的)将一些 JSON 传递给服务器。

JSON 的某些内容包含单引号,因此我想确保在传递给脚本之前对任何单引号进行转义。

我尝试了以下方法:

> irb
> 1.9.3p194 :001 > x = "that's an awesome string"
>  => "that's an awesome string" 
> 1.9.3p194 :002 > x.sub("'", "\'")
>  => "that's an awesome string" 
> 1.9.3p194 :003 > x.sub("'", "\\'")
>  => "thats an awesome strings an awesome string"

但似乎无法正确使用语法。

4

4 回答 4

39

sub("'", "\'")不起作用的原因是因为"\'"是一样的"'"。在双引号内,单引号的转义是可选的。

原因sub("'", "\\'")不起作用是因为"\\'"扩展为反斜杠后跟单引号。在suborgsub参数中,后跟一些字符的反斜杠具有与相应的全局变量相当的特殊含义。特别是在这种情况下,全局变量$'保存最后一个匹配点之后的子字符串。您的"\\'"内部subgsub论点位置指的是类似的事情。为了避免这种特殊约定,您应该将替换字符串放在一个块中而不是一个参数中,并且由于您想要匹配的不仅仅是一个,您应该使用gsub而不是sub

gsub("'"){"\\'"}
于 2012-10-03T02:08:55.847 回答
3

你为什么不使用 JSON gem?

require 'json'
some_object = {'a string' => "this isn't escaped because JSON handles it.", 'b' => 2}

puts some_object.to_json
=> {"a string":"this isn't escaped because JSON handles it.","b":2}

还有一个往返示例:

require 'pp'
pp JSON[some_object.to_json]
=> {
    "a string" => "this isn't escaped because JSON handles it.",
        "b" => 2
}

还有一个带双引号的例子:

some_object = {
  'a string'       => "this isn't escaped because JSON handles it.",
  'another string' => 'double-quotes get "escaped"'
}
puts some_object.to_json
=> {
            "a string" => "this isn't escaped because JSON handles it.",
      "another string" => "double-quotes get \"escaped\""
  }
于 2012-10-03T00:12:57.910 回答
2

如果您试图转义单引号(撇号),您可能还想转义双引号。(这将适用于 Javascript/JSON)

最简单的方法是使用escape_javascript http://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html它“为 JavaScript 段转义回车和单引号和双引号”。

注意这仅适用于Ruby on Rails,不适用于普通 Ruby。但是,您可以使用以下内容为普通 Ruby 制作一个 polyfill:

JS_ESCAPE_MAP   =   { '\\' => '\\\\', '</' => '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" }

def escape_javascript(javascript)
  if javascript
    result = javascript.gsub(/(\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] }
  else
    ''
  end
end
于 2015-07-07T20:39:44.270 回答
-2

试试这种方式,使用反斜杠转义:

puts 'sean\'s'

输出应该是:

sean's
于 2017-01-23T03:43:19.130 回答