Como escapar de caracteres especiais na construção de uma string JSON?

200

Aqui está minha string

{
    'user': {
        'name': 'abc',
        'fx': {
            'message': {
                'color': 'red'
            },
            'user': {
                'color': 'blue'
            }
        }
    },
    'timestamp': '2013-10-04T08: 10: 41+0100',
    'message': 'I'mABC..',
    'nanotime': '19993363098581330'
}    

Aqui, a mensagem contém aspas simples, que é igual à cotação usada no JSON. O que faço é preencher uma sequência de caracteres das entradas do usuário, como mensagem. Então, preciso escapar desse tipo de cenário especial que quebra o código. Mas, além da substituição de cadeias, existe alguma maneira de fazê-las escapar, mas ainda permitir que o HTML as processe de volta à mensagem correta?

dinesh707
fonte
45
O JSON usa apenas aspas duplas, não aspas simples, consulte json.org
Niels Bom
4
A RFC 4627 afirma que os analisadores devem poder analisar o JSON conforme (parágrafo 4) e podem oferecer suporte a extensões não JSON adicionais. No entanto, o parágrafo 5 afirma enfaticamente que todos os produtores (geradores) DEVEM produzir APENAS 100% de JSON compatível. Produzir JSON com caracteres de quadro que não precisam ser escapados é uma péssima idéia. Considere substituir seus apóstrofos por aspas. ietf.org/rfc/rfc4627.txt
Luv2code
3
@ Luv2code Enquanto os pontos que você está fazendo permanecem verdadeiros, observe que você está citando uma especificação obsoleta. Ao ler RFCs, sempre use a versão tools.ietf.org/html , não a versão em texto. As versões HTML são mais fáceis de ler e vincular às subseções e, o mais importante, na parte superior das versões HTML, há uma lista de todas as RFCs subseqüentes que atualizam ou obsoletas a que você está lendo. Se você tivesse acessado tools.ietf.org/html/rfc4627, veria que o RFC 4627 é obsoleto e foi substituído pelo RFC 7159 .
Mark Amery
3
Para as pessoas que lêem este no futuro, RFC 7159, por sua vez ficou obsoleto por tools.ietf.org/html/rfc8259
Joram van den Boezem
Post relacionado - As chaves JSON precisam estar entre aspas?
RBT

Respostas:

286

Uma string JSON deve ter aspas duplas, de acordo com as especificações , para que você não precise escapar '.
Se você precisar usar caracteres especiais em sua cadeia JSON, poderá escapar usando \caracteres.

Veja esta lista de caracteres especiais usados ​​no JSON:

\b  Backspace (ascii code 08)
\f  Form feed (ascii code 0C)
\n  New line
\r  Carriage return
\t  Tab
\"  Double quote
\\  Backslash character


No entanto, mesmo que seja totalmente contrário às especificações, o autor pode usar \'.

Isso é ruim porque:

  • É contrário às especificações
  • Não é mais uma sequência válida de JSON

Mas funciona, como você deseja ou não.

Para novos leitores, sempre use aspas duplas para suas strings json.

AlexB
fonte
30
"strings json com aspas simples" ? Isso não faz sentido; seqüências de caracteres em JSON só podem ser citadas duas vezes. Experimente JSON.parse("'foo'")no console do navegador, por exemplo, e observe o SyntaxError: Unexpected token '. A especificação JSON é realmente simples e clara sobre isso. Não existe uma sequência de escape no JSON para aspas simples, e uma sequência JSON não pode ser entre aspas simples.
Mark Amery
15
Até a atualização supostamente esclarecedora dessa resposta é ruim. Embora tecnicamente verdadeiro, é enganoso dizer que " você não precisa" escapar ', da mesma maneira que é tecnicamente verdadeiro, mas enganoso dizer que legalmente você não precisa matar crianças. Mais correto seria dizer que você não pode escapar '. \'é uma sequência de escape ilegal e, se você usá-lo, seu JSON não é um JSON válido e qualquer analisador JSON irá sufocá-lo. (Certamente de JavaScript JSON.parsedo e Python json.loadsafazeres.)
Mark Amery
2
Essa resposta continua sem sentido depois de muitas edições. Você afirma, erroneamente, que o uso de seqüências de citação simples em JSON e a \'sequência de escape "funciona como você deseja ou não" . Isto é falso. Desafio você a exibir qualquer analisador JSON em uso popular que não engasgue com seqüências de citação simples ou na \'sequência. Eu já apontei que JSON.parse("'foo'")e JSON.parse('"\\\'"') (em JavaScript) e json.loads("'foo'")e json.loads('"\\\'"')(em Python) ambos lançam exceções. Qual é a sua base para a alegação de que o uso dessas construções "funciona"?
Mark Amery
10
@ Citação interessante Luv2code. Você está interpretando mal um pouco; isso não significa que qualquer personagem possa ser escapado simplesmente colocando uma barra invertida na frente dele. Uma citação mais completa é "Qualquer caractere pode ser escapado. Se o caractere estiver no Plano Multilíngue Básico (U + 0000 a U + FFFF), ele poderá ser representado como uma sequência de seis caracteres . ... Como alternativa, existem dois seqüência de caracteres escapar representações de alguns personagens populares. "(ênfase minha). Está dizendo que você pode escapar 'como \u0027, não que você possa escapar como \'.
Mark Amery
2
@ Luv2code ainda, isso significa que meu comentário votado afirmando que "você não pode escapar '" (e comparando esse ato ao assassinato de crianças!) Está tecnicamente errado; mais preciso é dizer que você pode escapar, apenas não como \'. Eu não tinha percebido que a versão RFC das especificações se referia a seqüências como \u0027uma maneira de "escapar" dos caracteres que eles representam. O ponto chave que \'é ilegal, no entanto, ainda é verdadeiro e importante.
Mark Amery
362

Estou chocado com a presença de desinformação altamente votada em uma pergunta tão vista sobre um tópico básico.

As cadeias JSON não podem ser citadas com aspas simples . As várias versões da especificação ( o original de Douglas Crockford, a versão ECMA e a versão IETF ) afirmam que as strings devem ser citadas com aspas duplas. Esta não é uma questão teórica, nem uma questão de opinião, como sugere a resposta aceita atualmente; qualquer analisador JSON do mundo real cometerá um erro se você tentar fazer com que ele analise uma sequência de aspas simples.

As versões de Crockford e ECMA até exibem a definição de uma string usando uma imagem bonita, o que deve tornar o ponto inequivocamente claro:

Imagem mostrando a definição de uma sequência da especificação JSON

A imagem bonita também lista todas as seqüências de escape legítimas dentro de uma string JSON:

  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u seguido por quatro dígitos hexadecimais

Observe que, ao contrário do absurdo em algumas outras respostas aqui, \'nunca é uma sequência de escape válida em uma sequência JSON. Não precisa ser, porque as strings JSON sempre são aspas duplas.

Por fim, você normalmente não precisa pensar em escapar de caracteres quando gerar JSON de forma programática (embora seja claro que editará manualmente, por exemplo, um arquivo de configuração baseado em JSON). Em vez disso, forme a estrutura de dados que você deseja codificar usando qualquer tipo de mapa, matriz, sequência, número, booleano e nulo nativo que seu idioma possua e, em seguida, codifique-o para JSON com uma função de codificação JSON. Essa função provavelmente está embutida em qualquer linguagem que você esteja usando, como JavaScript JSON.stringify, PHP json_encodeou Python.json.dumps. Se você estiver usando um idioma que não possui essa funcionalidade incorporada, provavelmente poderá encontrar uma biblioteca de análise e codificação JSON para usar. Se você simplesmente usar funções de linguagem ou biblioteca para converter itens de e para JSON, nunca precisará conhecer as regras de escape do JSON. Isto é o que a pergunta equivocada que deveria fazer aqui deveria ter feito.

Mark Amery
fonte
4 bytes hexadecimais ou mordidelas ?
leetbacoon
36

Todo mundo está falando sobre como escapar 'em um 'literal de string entre aspas. Há um problema muito maior aqui: literais de string com aspas simples não são JSON válidos . JSON é baseado em JavaScript, mas não é a mesma coisa. Se você estiver escrevendo um literal de objeto dentro do código JavaScript, tudo bem; se você realmente precisar de JSON, precisará usar ".

Com strings de aspas duplas, você não precisará escapar do '. (E se você quisesse um literal "na string, você usaria \".)

David Knipe
fonte
1
Olá, você disse que com aspas duplas, não precisará escapar do '. Exemplo inimigo, se meu valor de string for "Member's_id" : 4, você está dizendo que ele não precisa escapar? Aparentemente, estou tendo um problema em que está dando um erro de codificação incorreta: UTF-8 e está sendo lido como Member�s. É um arquivo json gerado manualmente.
Shubham
1
'em um literal de cadeia JSON não deve ser escapado. Você copiou e colou de algum lugar? Talvez seja realmente um \u2019, não um apóstrofo. Meu palpite: alguém digitou no MS Word, o que o transformou em aspas porque acha melhor. Gramaticalmente, o bom e velho apóstrofo de caracteres ASCII ( 'também conhecido como \x27"aspas simples" até agora)) é o que você deseja. Ainda assim, seria bom corrigir o problema de codificação de caracteres, caso haja outros problemas semelhantes. Portanto, escolha uma codificação de caracteres e use-a para leituras e gravações. Ou escape usando \u.
David Knipe
7

A maioria dessas respostas não responde à pergunta ou é desnecessariamente longa na explicação.

OK, então o JSON usa aspas duplas, entendemos isso!

Eu estava tentando usar o JQuery AJAX para postar dados JSON no servidor e depois retornar as mesmas informações. A melhor solução para a pergunta postada que encontrei foi usar:

var d = {
    name: 'whatever',
    address: 'whatever',
    DOB: '01/01/2001'
}
$.ajax({
    type: "POST",
    url: 'some/url',
    dataType: 'json',
    data: JSON.stringify(d),
    ...
}

Isso escapará dos personagens para você.

Isso também foi sugerido por Mark Amery, ótima resposta.

Espero que isso ajude alguém.

Arrebentar
fonte
0

Pode ser que eu esteja muito atrasado para a festa, mas isso analisará / escapará aspas simples (não quero entrar em uma batalha em análise vs fuga) ..

JSON.parse("\"'\"")
YankTHEcode
fonte
0

A resposta à pergunta direta:
para garantir a segurança, substitua o caractere necessário por \ u + valor hexadecimal de 4 dígitos

Exemplo: se você quiser escapar do apóstrofo, substitua por \ u0027
D'Amico se torna D \ u0027Amico

REFERÊNCIA AGRADÁVEL: http://es5.github.io/x7.html#x7.8.4

https://mathiasbynens.be/notes/javascript-escapes

Luigi D'Amico
fonte
-1 para as referências. A pergunta é sobre JSON, mas suas referências vinculadas são sobre JavaScript e listam sequências de escape que não são válidas em JavaScript \'.
Mark Amery #
Obrigado Mark - Eu realmente só queria dar um ângulo alternativo - dependendo de quem chega aqui pode achar isso útil. Mas eu entendo o seu ponto de vista sobre JSON e Javascript - Obrigado por ser um Ninja nos fóruns.
Luigi D'Amico
0

Use encodeURIComponent () para codificar a sequência.

Por exemplo. var product_list = encodeURIComponent (JSON.stringify (product_list));

Você não precisa decodificá-lo, pois o servidor da Web faz o mesmo automaticamente.

Sanju Kaniyamattam
fonte
0

Usando literais de modelo ...

var json = `{"1440167924916":{"id":1440167924916,"type":"text","content":"It's a test!"}}`;
Ruben
fonte
-2

Acho que todos concordamos que jsons com aspas simples não são reais. Seja como for, ainda precisamos abordar a questão de escapar "dentro de uma string json com aspas duplas, na ausência de bibliotecas para fazer isso por nós.

Substituir cada "por um" NÃO É SUFICIENTE: O usuário pode inserir a entrada: \ e a análise falha novamente (pense no porquê).

Em vez disso, primeiro substitua cada \ por \ (barra invertida dupla). Somente então, substitua cada "por" (barra invertida seguida por ").

Tom Blitz
fonte
-2

Para permitir aspas simples na sequência de citação duplamente para fins de json, você duplica a aspas simples. {"X": "Qual é a pergunta"} ==> {"X": "Qual é a pergunta"}

/codereview/69266/json-conversion-to-single-quotes

A sequência \ 'é inválida.

4T2G
fonte
2
Dobrar uma citação única em uma string JSON não escapa. Significa apenas que sua string contém duas aspas simples, em vez de uma.
Mark Amery
-15

sobre o post de AlexB:

 \'  Apostrophe or single quote
 \"  Double quote

escapar aspas simples é válido apenas em cadeias json com aspas simples escapar aspas simples é válido apenas em cadeias json
com aspas duplas

exemplo:

'Bart\'s car'       -> valid
'Bart says \"Hi\"'  -> invalid
Bart
fonte
14
Cadeias de caracteres entre aspas simples não são legais no JSON. JSON não é javascript. JSON não permite escapar da aspas simples. Veja json.org para o documento muito simples da sintaxe JSON.
srm
3
voto negativo - porque aspas simples jsons não são válidas!
DominikAngerer
Aspas simples são inválidas no json. Por favor, mostre uma amostra de trabalho, se isso for possível
Rohith 03/02