JSON.decode
为此使用会带来您必须注意的重大缺点:
- 您必须将字符串用双引号括起来
- 许多字符不受支持,必须自己转义。例如,将以下任何内容传递给
JSON.decode
(将它们用双引号括起来后)将出错,即使这些都是有效的:\\n
, \n
, \\0
,a"a
- 它不支持十六进制转义:
\\x45
- 它不支持 Unicode 代码点序列:
\\u{045}
还有其他注意事项。从本质上讲,JSON.decode
用于此目的是一种黑客行为,并不像您一直期望的那样工作。您应该坚持使用该JSON
库来处理 JSON,而不是用于字符串操作。
我最近自己遇到了这个问题,想要一个强大的解码器,所以我最终自己写了一个。它是完整且经过彻底测试的,可在此处获得:https : //github.com/iansan5653/unraw。它尽可能地模仿 JavaScript 标准。
解释:
源代码大约有 250 行,所以我不会在这里全部包含它,但本质上它使用以下正则表达式来查找所有转义序列,然后使用parseInt(string, 16)
解码 base-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');
// yields "http%3A%2F%2Fexample.com"
// Then you can use decodeURIComponent to further decode it:
let step2 = decodeURIComponent(step1);
// yields http://example.com