web-dev-qa-db-fra.com

Comment puis-je échapper à une citation unique en Ruby?

Je passe un JSON à un serveur via un script (pas le mien) qui accepte le JSON en tant que chaîne.

Une partie du contenu du code JSON contient des guillemets simples, aussi je veux m'assurer que tous les guillemets simples sont échappés avant d'être transmis au script.

J'ai essayé ce qui suit:

> 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"

mais n'arrive pas à comprendre la syntaxe.

22
Dave Sag

La raison pour laquelle sub("'", "\'") ne fonctionne pas est que "\'" est identique à "'". Dans les guillemets doubles, l'échappement d'un seul devis est facultatif.

La raison pour laquelle sub("'", "\\'") ne fonctionne pas est que "\\'" se développe en une barre oblique inversée suivie d'un guillemet simple. Dans l'argument sub ou gsub, une barre oblique inverse suivie de certains caractères a une signification particulière, comparable à la variable globale correspondante. Dans ce cas en particulier, la variable globale $' contient la sous-chaîne après le dernier point correspondant. Votre position "\\'" dans sub ou gsub fait référence à une chose similaire. Afin d'éviter cette convention spéciale, vous devez placer la chaîne de remplacement dans un bloc au lieu d'un argument. Et puisque vous souhaitez en faire correspondre un seul, vous devez utiliser gsub au lieu de sub:

gsub("'"){"\\'"}
33
sawa

Pourquoi n'utilisez-vous pas la gemme JSON?

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}

Et un exemple aller-retour:

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

Et un exemple avec des guillemets:

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\""
  }
3
the Tin Man

Il est probable que, si vous essayez d'échapper à une simple citation (apostrophe), vous souhaitiez également échapper à des guillemets doubles. (Cela s’appliquerait à Javascript/JSON) 

Le moyen le plus simple consiste à utiliser escape_javascripthttp://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html it "Echappe les retours à la chaine et les guillemets simples et doubles pour les segments JavaScript."

REMARQUE: cela ne fonctionne que pour Ruby on Rails , pas simplement Ruby. Cependant, vous pouvez créer un polyfill pour Ruby ordinaire en utilisant quelque chose comme ceci:

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
1
aaron-coding

Essayez de cette façon, utilisez une barre oblique inverse pour vous échapper:

puts 'sean\'s'

la sortie devrait être:

sean's
0
Sean Das