Je ne sais pas comment cela s'appelle donc j'ai du mal à le rechercher. Comment puis-je décoder une chaîne avec unicode de http\u00253A\u00252F\u00252Fexample.com
à http://example.com
avec JavaScript? J'ai essayé unescape
, decodeURI
et decodeURIComponent
je suppose que la seule chose qui reste est le remplacement de la chaîne.
EDIT: La chaîne n'est pas typée, mais plutôt une sous-chaîne d'un autre morceau de code. Donc, pour résoudre le problème, vous devez commencer par quelque chose comme ceci:
var s = 'http\\u00253A\\u00252F\\u00252Fexample.com';
J'espère que cela montre pourquoi unescape () ne fonctionne pas.
javascript
decode
urldecode
styfle
la source
la source
Réponses:
Modifier (2017-10-12) :
@MechaLynx et @ Kevin-Weber notent qu'il
unescape()
est déconseillé dans les environnements non-navigateur et n'existe pas dans TypeScript.decodeURIComponent
est un remplacement instantané. Pour une compatibilité plus large, utilisez plutôt ce qui suit:decodeURIComponent(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"')); > 'http://example.com'
Réponse originale:
unescape(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"')); > 'http://example.com'
Vous pouvez décharger tout le travail vers
JSON.parse
la source
unescape(JSON.parse('"' + s + '"'));
Quelle est la raison des citations supplémentaires? Cela rend-il JSON valide?fromCharCode
approche: jsperf.com/unicode-func-vs-json-parseJSON.parse('"' + s + '"')
lorsque vous traitez avec des données non approuvées à laJSON.parse('"' + s.replace('"', '\\"') + '"')
place, sinon votre code sera interrompu lorsque l'entrée contient des guillemets.unescape()
a été obsolète,decodeURIComponent()
fonctionne de la même manière queunescape()
dans ce cas, alors remplacez-le simplement par cela et vous êtes bon.MISE À JOUR : Veuillez noter qu'il s'agit d'une solution qui devrait s'appliquer aux navigateurs plus anciens ou aux plates-formes non-navigateur, et qui est conservée à des fins pédagogiques. Veuillez vous référer à la réponse de @radicand ci-dessous pour une réponse plus à jour.
Il s'agit d'une chaîne d'échappement unicode. La chaîne a d'abord été échappée, puis encodée avec unicode. Pour revenir à la normale:
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
Pour expliquer: j'utilise une expression régulière pour rechercher
\u0025
. Cependant, comme je n'ai besoin que d'une partie de cette chaîne pour mon opération de remplacement, j'utilise des parenthèses pour isoler la partie que je vais réutiliser0025
. Cette partie isolée s'appelle un groupe.La
gi
partie à la fin de l'expression indique qu'elle doit correspondre à toutes les instances de la chaîne, pas seulement la première, et que la correspondance doit être insensible à la casse. Cela peut sembler inutile étant donné l'exemple, mais cela ajoute de la polyvalence.Maintenant, pour convertir d'une chaîne à l'autre, je dois exécuter quelques étapes sur chaque groupe de chaque correspondance, et je ne peux pas le faire en transformant simplement la chaîne. Heureusement, l'opération String.replace peut accepter une fonction, qui sera exécutée pour chaque correspondance. Le retour de cette fonction remplacera la correspondance elle-même dans la chaîne.
J'utilise le deuxième paramètre que cette fonction accepte, qui est le groupe que je dois utiliser, et je le transforme en séquence utf-8 équivalente, puis j'utilise la
unescape
fonction intégrée pour décoder la chaîne sous sa forme appropriée.la source
\u
préfixe et un nombre hexadécimal à 4 caractères (lettres ou chiffres). Comment fonctionne la fonction de la méthode de remplacement?var r = /\\u([\d\w]{1,})/gi;
JSON.parse
approche: jsperf.com/unicode-func-vs-json-parseunescape()
peut utiliser à ladecodeURIComponent()
place. Cela fonctionne à l'identique dans ce cas. Je recommanderais cependant l'approche de radicand, car elle est plus simple, tout aussi prise en charge et plus rapide à exécuter, avec les mêmes résultats (assurez-vous de lire les commentaires cependant).Notez que l'utilisation de
unescape()
est obsolète et ne fonctionne pas avec le compilateur TypeScript, par exemple.Sur la base de la réponse de radicand et de la section commentaires ci-dessous, voici une solution mise à jour:
var string = "http\\u00253A\\u00252F\\u00252Fexample.com"; decodeURIComponent(JSON.parse('"' + string.replace(/\"/g, '\\"') + '"'));
http://example.com
la source
Je n'ai pas assez de représentants pour mettre ceci sous les commentaires des réponses existantes:
unescape
n'est obsolète que pour travailler avec des URI (ou n'importe quel utf-8 encodé), ce qui est probablement le cas pour les besoins de la plupart des gens.encodeURIComponent
convertit une chaîne js en UTF-8 échappé etdecodeURIComponent
ne fonctionne que sur les octets UTF-8 échappés. Cela génère une erreur pour quelque chose commedecodeURIComponent('%a9'); // error
parce que l'ascii étendu n'est pas valide utf-8 (même si c'est toujours une valeur unicode), alors queunescape('%a9'); // ©
vous devez connaître vos données lorsque vous utilisez decodeURIComponent.decodeURIComponent ne fonctionnera pas sur
"%C2"
ou sur tout octet isolé0x7f
car dans utf-8, cela indique une partie d'un substitut. Cependant,decodeURIComponent("%C2%A9") //gives you ©
Unescape ne fonctionnerait pas correctement sur cela// ©
ET il ne générerait pas d'erreur, donc unescape peut conduire à un code bogué si vous ne connaissez pas vos données.la source
L'utilisation
JSON.decode
pour cela présente des inconvénients importants dont vous devez être conscient:JSON.decode
(après les envelopper dans des guillemets) sera erreur même si ceux - ci sont valides:\\n
,\n
,\\0
,a"a
\\x45
\\u{045}
Il y a également d'autres mises en garde. Essentiellement, utiliser
JSON.decode
à cette fin est un hack et ne fonctionne pas comme vous pourriez toujours vous y attendre. Vous devez vous en tenir à l'utilisation de laJSON
bibliothèque pour gérer JSON, pas pour les opérations de chaîne.J'ai récemment rencontré ce problème moi-même et je voulais un décodeur robuste, alors j'ai fini par en écrire un moi-même. Il est complet et minutieusement testé et est disponible ici: https://github.com/iansan5653/unraw . Il imite le plus fidèlement possible la norme JavaScript.
Explication:
La source est d'environ 250 lignes, donc je ne vais pas tout inclure ici, mais elle utilise essentiellement le Regex suivant pour trouver toutes les séquences d'échappement, puis les analyse en utilisant
parseInt(string, 16)
pour décoder les nombres en base 16, puisString.fromCodePoint(number)
pour obtenir le caractère correspondant:/\\(?:(\\)|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
Commenté (REMARQUE: cette expression régulière correspond à toutes les séquences d'échappement, y compris les séquences non valides. Si la chaîne génère une erreur dans JS, elle renvoie une erreur dans ma bibliothèque [c'est-à-dire, une
'\x!!'
erreur]):/ \\ # 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
Exemple
En utilisant cette bibliothèque:
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
la source