Die Verwendung JSON.decode
hierfür bringt erhebliche Nachteile mit sich, die Sie beachten müssen:
- Sie müssen die Zeichenfolge in doppelte Anführungszeichen setzen
- Viele Zeichen werden nicht unterstützt und müssen selbst maskiert werden. Zum Beispiel, um eine der folgenden vorbei
JSON.decode
(nach ihnen in doppelten Anführungszeichen Einwickeln) werden Fehler , obwohl diese sind alle gültig: \\n
, \n
, \\0
,a"a
- Hexadezimale Escapezeichen werden nicht unterstützt:
\\x45
- Unicode-Codepunktsequenzen werden nicht unterstützt:
\\u{045}
Es gibt auch andere Einschränkungen. Im Wesentlichen ist die Verwendung JSON.decode
für diesen Zweck ein Hack und funktioniert nicht so, wie Sie es immer erwarten. Sie sollten die JSON
Bibliothek weiterhin für JSON verwenden, nicht für Zeichenfolgenoperationen.
Ich bin kürzlich selbst auf dieses Problem gestoßen und wollte einen robusten Decoder, also habe ich selbst einen geschrieben. Es ist vollständig und gründlich getestet und hier verfügbar: https://github.com/iansan5653/unraw . Es ahmt den JavaScript-Standard so genau wie möglich nach.
Erläuterung:
Die Quelle besteht aus ungefähr 250 Zeilen, daher werde ich hier nicht alles einfügen, aber im Wesentlichen wird der folgende Regex verwendet, um alle Escape-Sequenzen zu finden und sie dann zu analysieren parseInt(string, 16)
, um die Basis-16-Zahlen zu dekodieren und dann String.fromCodePoint(number)
das entsprechende Zeichen zu erhalten:
/\\(?:(\\)|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
Kommentiert (HINWEIS: Dieser reguläre Ausdruck entspricht allen Escape-Sequenzen, einschließlich ungültiger. Wenn die Zeichenfolge einen Fehler in JS auslösen würde, würde dies einen Fehler in meiner Bibliothek auslösen [dh '\x!!'
Fehler verursachen]):
/
\\ # 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
Beispiel
Verwenden dieser Bibliothek:
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