2012-10-03 15 views
16

Sto passando alcuni JSON a un server tramite uno script (non il mio) che accetta JSON come stringa.Come faccio a uscire da una singola citazione in Ruby?

Alcuni dei contenuti del JSON contengono virgolette singole, quindi voglio assicurarmi che tutte le virgolette siano sfuggite prima di essere passate allo script.

Ho provato quanto segue:

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

ma non riesco a ottenere la giusta sintassi.

+3

Come sono le i valori "passati"? Perché * quello * sembra il difetto; JSON gestisce le virgolette incorporate, e una volta che è * dentro * una stringa di Ruby, non ha importanza. –

+0

Se "via script" significa sottoprocesso, per favore aprilo * senza * creando una subshell che risolverà questo problema interamente in sistemi simil-Unix. (Non sono sicuro che la roba di Win32 sia sufficientemente aggiornata per questa assurdità.) –

+2

'x.sub ("'", "\\\\'") 'fa quello che stai cercando di fare. Ma il modo in cui Tin Man è il modo giusto per gettarsi a jsonify. – Zabba

risposta

3

Perché non usi la gemma 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} 

E un esempio di andata e ritorno:

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

E un esempio con doppi apici:

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\"" 
    } 
+0

Non si utilizza la gemma JSON perché non è effettivamente necessaria e non è in esecuzione sul computer dei miei clienti. –

26

Il motivo sub("'", "\'") non funziona è perché "\'" è lo stesso di "'" . Tra virgolette doppie, l'escape di una singola citazione è facoltativo.

Il motivo sub("'", "\\'") non funziona perché "\\'" si espande in una barra rovesciata seguita da una virgoletta singola. Nell'argomento sub o gsub, una barra rovesciata seguita da alcuni caratteri ha un significato speciale paragonabile alla corrispondente variabile globale. In particolare in questo caso, la variabile globale $' mantiene la sottostringa dopo l'ultimo punto di corrispondenza. Il tuo "\\'" all'interno di sub o gsub posizione argomento si riferisce a una cosa simile. Al fine di evitare questo speciale convenzione, si dovrebbe mettere la stringa di sostituzione in un blocco, invece di un argomento, e dal momento che si desidera far corrispondere non solo uno, si dovrebbe usare gsub invece di sub:

gsub("'"){"\\'"} 
+0

Purtroppo non funziona davvero –

+0

@DaveSag Funziona. – sawa

+0

No - questo dà "" che è una stringa fantastica "' –

1

E 'probabile che se stai cercando di sfuggire a una singola virgoletta (apostrofo), vuoi anche sfuggire alle virgolette doppie. (Ciò si applica per Javascript/JSON)

Il modo più semplice è utilizzare escape_javascripthttp://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html "Escapes ritorni a capo e virgolette singole e doppie per segmenti JavaScript".

NOTA questo funziona solo per Ruby on Rails, non semplice Ruby. Tuttavia si può fare un polyfill per piano di Ruby utilizzando qualcosa di simile:

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

provare in questo modo, utilizzare backslash per fuggire:

puts 'sean\'s' 

uscita dovrebbe essere:

sean's 
Problemi correlati