これに使用JSON.decode
すると、次の点に注意する必要がある重大な欠点があります。
- 文字列は二重引用符で囲む必要があります
- 多くの文字はサポートされていないため、エスケープする必要があります。たとえば、に次のいずれかを渡す
JSON.decode
(二重引用符でそれらをラップした後)は、これらはすべて有効であってもエラーになります:\\n
、\n
、\\0
、a"a
- 16進エスケープはサポートされていません。
\\x45
- Unicodeコードポイントシーケンスはサポートしていません。
\\u{045}
他にも注意点があります。基本的に、JSON.decode
この目的での使用はハックであり、常に期待するようには機能しません。JSON
文字列操作ではなく、ライブラリを使用してJSONを処理することに固執する必要があります。
私は最近この問題に自分で遭遇し、堅牢なデコーダーが欲しかったので、自分で作成することになりました。完全で徹底的にテストされており、https://github.com/iansan5653/unrawから入手できます。これは、JavaScript標準を可能な限り模倣しています。
説明:
ソースは約250行なので、ここにはすべて含めませんが、基本的には次の正規表現を使用してすべてのエスケープシーケンスを検索し、それらを解析してparseInt(string, 16)
16進数をデコードしString.fromCodePoint(number)
、対応する文字を取得します。
/\\(?:(\\)|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
コメント(注:この正規表現は、無効なものを含むすべてのエスケープシーケンスに一致します。文字列がJSでエラーをスローすると、ライブラリでエラーがスローされます[つまり、'\x!!'
エラーが発生します]):
/
\\ # 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
例
そのライブラリの使用:
import unraw from "unraw";
let step1 = unraw('http\\u00253A\\u00252F\\u00252Fexample.com');
let step2 = decodeURIComponent(step1);