L'utilisation JSON.decode
pour cela présente des inconvénients importants dont vous devez être conscient:
- Vous devez mettre la chaîne entre guillemets
- De nombreux caractères ne sont pas pris en charge et doivent eux-mêmes être échappés. Par exemple, en passant une des conditions suivantes à
JSON.decode
(après les envelopper dans des guillemets) sera erreur même si ceux - ci sont valides: \\n
, \n
, \\0
,a"a
- Il ne prend pas en charge les échappements hexadécimaux:
\\x45
- Il ne prend pas en charge les séquences de points de code Unicode:
\\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 la JSON
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, puis String.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');
let step2 = decodeURIComponent(step1);