Não tenho certeza de como é chamado, então estou tendo problemas para pesquisar. Como posso decodificar uma string com Unicode de http\u00253A\u00252F\u00252Fexample.com
para http://example.com
com JavaScript? Eu tentei unescape
, decodeURI
e decodeURIComponent
então acho que a única coisa que resta é a substituição da corda.
EDIT: A string não é digitada, mas sim uma substring de outro trecho de código. Portanto, para resolver o problema, você deve começar com algo assim:
var s = 'http\\u00253A\\u00252F\\u00252Fexample.com';
Espero que isso mostre por que unescape () não funciona.
javascript
decode
urldecode
estilo
fonte
fonte
Respostas:
Editar (12-10-2017) :
@MechaLynx e @ Kevin-Weber observam que
unescape()
foi descontinuado em ambientes sem navegador e não existe no TypeScript.decodeURIComponent
é um substituto imediato. Para uma compatibilidade mais ampla, use o seguinte:decodeURIComponent(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"')); > 'http://example.com'
Resposta original:
unescape(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"')); > 'http://example.com'
Você pode descarregar todo o trabalho para
JSON.parse
fonte
unescape(JSON.parse('"' + s + '"'));
Qual é a razão das citações extras? Isso o torna um JSON válido?fromCharCode
abordagem: jsperf.com/unicode-func-vs-json-parseJSON.parse('"' + s + '"')
ao lidar com dados não confiáveisJSON.parse('"' + s.replace('"', '\\"') + '"')
, caso contrário, seu código será interrompido quando a entrada contiver aspas.unescape()
foi descontinuado,decodeURIComponent()
funciona de forma idênticaunescape()
neste caso, então apenas substitua por isso e está tudo bem.ATUALIZAÇÃO : Por favor, note que esta é uma solução que deve ser aplicada a navegadores mais antigos ou plataformas sem navegadores e é mantida ativa para fins de instrução. Consulte a resposta de @radicand abaixo para obter uma resposta mais atualizada.
Esta é uma string unicode com escape. Primeiro, a string foi escapada e, em seguida, codificada com Unicode. Para converter de volta ao normal:
var x = "http\\u00253A\\u00252F\\u00252Fexample.com"; var r = /\\u([\d\w]{4})/gi; x = x.replace(r, function (match, grp) { return String.fromCharCode(parseInt(grp, 16)); } ); console.log(x); // http%3A%2F%2Fexample.com x = unescape(x); console.log(x); // http://example.com
Para explicar: eu uso uma expressão regular para procurar
\u0025
. No entanto, como preciso apenas de uma parte dessa string para minha operação de substituição, uso parênteses para isolar a parte que vou reutilizar0025
,. Essa parte isolada é chamada de grupo.A
gi
parte no final da expressão indica que ela deve corresponder a todas as instâncias da string, não apenas à primeira, e que a correspondência deve ser insensível a maiúsculas e minúsculas. Isso pode parecer desnecessário dado o exemplo, mas adiciona versatilidade.Agora, para converter de uma string para a próxima, preciso executar algumas etapas em cada grupo de cada correspondência, e não posso fazer isso simplesmente transformando a string. Felizmente, a operação String.replace pode aceitar uma função, que será executada para cada correspondência. O retorno dessa função substituirá a própria correspondência na string.
Eu uso o segundo parâmetro que esta função aceita, que é o grupo que preciso usar, e transformo-o na sequência utf-8 equivalente e, em seguida, uso a
unescape
função interna para decodificar a string em sua forma adequada.fonte
\u
prefixo e não um número hexadecimal de 4 caracteres (letras ou números). Como funciona a função no método de substituição?var r = /\\u([\d\w]{1,})/gi;
JSON.parse
abordagem: jsperf.com/unicode-func-vs-json-parseunescape()
pode usardecodeURIComponent()
. Funciona de forma idêntica neste caso. Eu recomendaria a abordagem de radicand no entanto, por ser mais simples, tão suportada e mais rápida de executar, com os mesmos resultados (certifique-se de ler os comentários, no entanto).Observe que o uso de
unescape()
está obsoleto e não funciona com o compilador TypeScript, por exemplo.Com base na resposta de Radicand e na seção de comentários abaixo, aqui está uma solução atualizada:
var string = "http\\u00253A\\u00252F\\u00252Fexample.com"; decodeURIComponent(JSON.parse('"' + string.replace(/\"/g, '\\"') + '"'));
http://example.com
fonte
Não tenho representante suficiente para colocar isso em comentários às respostas existentes:
unescape
só está obsoleto para trabalhar com URIs (ou qualquer utf-8 codificado), o que provavelmente é o caso para as necessidades da maioria das pessoas.encodeURIComponent
converte uma string js em UTF-8 de escape edecodeURIComponent
só funciona em bytes UTF-8 de escape. Ele lança um erro para algo comodecodeURIComponent('%a9'); // error
porque ascii estendido não é utf-8 válido (mesmo que ainda seja um valor Unicode), enquantounescape('%a9'); // ©
So você precisa saber seus dados ao usar decodeURIComponent.decodeURIComponent não funcionará em
"%C2"
nenhum byte solitário0x7f
porque em utf-8 isso indica parte de um substituto. No entanto, odecodeURIComponent("%C2%A9") //gives you ©
Unescape não funcionaria corretamente nisso// ©
E não geraria um erro, então o unescape pode levar a um código com erros se você não souber seus dados.fonte
Usar
JSON.decode
para isso tem desvantagens significativas, das quais você deve estar ciente:JSON.decode
(depois de envolvê-los em aspas) irá erro mesmo que estes são todos válidos:\\n
,\n
,\\0
,a"a
\\x45
\\u{045}
Existem outras advertências também. Essencialmente, usar
JSON.decode
para esse propósito é um hack e não funciona da maneira que você sempre esperava. Você deve usar aJSON
biblioteca para lidar com JSON, não para operações de string.Recentemente, eu mesmo tive esse problema e queria um decodificador robusto, então acabei escrevendo um sozinho. Está completo e exaustivamente testado e está disponível aqui: https://github.com/iansan5653/unraw . Ele imita o padrão JavaScript o mais próximo possível.
Explicação:
A fonte tem cerca de 250 linhas, então não vou incluir tudo aqui, mas basicamente ele usa o seguinte Regex para encontrar todas as sequências de escape e depois as analisa usando
parseInt(string, 16)
para decodificar os números de base 16 eString.fromCodePoint(number)
obter o caractere correspondente:/\\(?:(\\)|x([\s\S]{0,2})|u(\{[^}]*\}?)|u([\s\S]{4})\\u([^{][\s\S]{0,3})|u([\s\S]{0,4})|([0-3]?[0-7]{1,2})|([\s\S])|$)/g
Comentado (OBSERVAÇÃO: esta regex corresponde a todas as sequências de escape, incluindo as inválidas. Se a string gerasse um erro em JS, ela geraria um erro em minha biblioteca [ou seja,
'\x!!'
erro de erro]):/ \\ # All escape sequences start with a backslash (?: # Starts a group of 'or' statements (\\) # If a second backslash is encountered, stop there (it's an escaped slash) | # or x([\s\S]{0,2}) # Match valid hexadecimal sequences | # or u(\{[^}]*\}?) # Match valid code point sequences | # or u([\s\S]{4})\\u([^{][\s\S]{0,3}) # Match surrogate code points which get parsed together | # or u([\s\S]{0,4}) # Match non-surrogate Unicode sequences | # or ([0-3]?[0-7]{1,2}) # Match deprecated octal sequences | # or ([\s\S]) # Match anything else ('.' doesn't match newlines) | # or $ # Match the end of the string ) # End the group of 'or' statements /g # Match as many instances as there are
Exemplo
Usando essa biblioteca:
import unraw from "unraw"; let step1 = unraw('http\\u00253A\\u00252F\\u00252Fexample.com'); // yields "http%3A%2F%2Fexample.com" // Then you can use decodeURIComponent to further decode it: let step2 = decodeURIComponent(step1); // yields http://example.com
fonte