如果你查看这个table here,它有一个Unicode字符的转义序列列表,这些转义序列实际上对我不起作用。
例如对于“%96”,它应该是 - ,我在尝试解码时遇到错误:
decodeURIComponent("%96");
URIError: URI malformed
如果我尝试编码“ - ”我实际得到:
encodeURIComponent("–");
"%E2%80%93"
我在互联网上搜索过,我看到了this page,它分别提到了使用escape和unescape与decodeURIComponent和encodeURIComponent。这似乎没有帮助,因为%96不会显示为“ - ”,无论我尝试什么,这当然不会起作用:
decodeURIComponent(escape("%96));
"%96"
不是很有帮助。
如何使用JavaScript将“%96”变成“ - ”(没有为我可能遇到的每个可能的unicode字符硬编码地图)?
答案 0 :(得分:4)
URI中的序列%XX
编码“八位字节”,即8位字节。这就提出了解码字节所指的Unicode字符的问题。如果我的记忆正确地为我服务,那么在旧版本的URI规范中,没有很好地定义了什么是charset。在URI规范的更高版本中,建议UTF-8是默认的编码字符集。也就是说,要解码一个字节序列,您将解码每个%XX
序列,然后使用UTF-8字符集将结果字节转换为字符串。
这解释了%96
无法解码的原因。十六进制0x96值不是有效的UTF-8序列。因为它超出了ASCII,所以在它之前需要一个特殊的修饰符字节来表示扩展字符。 (有关更多详细信息,请参阅UTF-8规范。)JavaScript encodeURIComponent()
和decodeURIComponent()
方法都假定为UTF-8(正如它们所应),因此我不希望%96
解码正确。
你引用的角色是U + 2013,一个短划线。您引用的页面如何从十六进制0x96(十进制150)获得一个en-dash?他们显然没有采用UTF-8编码,这是标准。它们不假设ASCII,不包含此字符。它们甚至不假设ISO-8859-1,这是一种标准编码,每个字符使用一个字节。事实证明他们正在假设特殊的Windows 1252代码页。也就是说,您尝试解码的URI假定用户在Windows计算机上,更糟糕的是,在Windows机器上使用英语(或其他一些西方语言)。
简而言之,您使用的表格很糟糕。它已过时并假定用户使用的是英文Windows系统。对非ASCII值进行编码的最新且正确的方法是将它们转换为UTF-8,然后使用%XX
对每个八位字节进行编码。这就是为什么当你试图对角色进行编码时你得到%E2%80%93
,这就是decodeURIComponent()
所期待的。您正在使用的URI未正确编码。如果您没有其他选择,您可以猜测URI是使用Windows 1252,自己转换字节,然后使用Windows 1252表来找出想要的Unicode值。但这有风险---你怎么知道哪个URI使用哪个表?这就是每个人都选择UTF-8的原因。如果可能的话,告诉谁给你这些URI以正确编码它们。
答案 1 :(得分:2)
发布社区wiki条目,因为它来自Carl Henderson的“构建可扩展网站”。该书说,重现这些例子的重要部分是可以的。您可以使用它创建“ - ”的特殊情况。
function escape_utf8(data) {
if (data == '' || data == null){
return '';
}
data = data.toString();
var buffer = '';
for(var i=0; i<data.length; i++){
var c = data.charCodeAt(i);
var bs = new Array();
if (c > 0x10000){
// 4 bytes
bs[0] = 0xF0 | ((c & 0x1C0000) >>> 18);
bs[1] = 0x80 | ((c & 0x3F000) >>> 12);
bs[2] = 0x80 | ((c & 0xFC0) >>> 6);
bs[3] = 0x80 | (c & 0x3F);
}else if (c > 0x800){
// 3 bytes
bs[0] = 0xE0 | ((c & 0xF000) >>> 12);
bs[1] = 0x80 | ((c & 0xFC0) >>> 6);
bs[2] = 0x80 | (c & 0x3F);
}else if (c > 0x80){
// 2 bytes
bs[0] = 0xC0 | ((c & 0x7C0) >>> 6);
bs[1] = 0x80 | (c & 0x3F);
}else{
// 1 byte
bs[0] = c;
}
for(var j=0; j<bs.length; j++){
var b = bs[j];
var hex = nibble_to_hex((b & 0xF0) >>> 4)
+ nibble_to_hex(b &0x0F);buffer += '%'+hex;
}
}
return buffer;
}
function nibble_to_hex(nibble){
var chars = '0123456789ABCDEF';
return chars.charAt(nibble);
}
答案 2 :(得分:1)
请参阅this question,具体为this answer:
有一种特殊的“%uNNNN”格式 编码Unicode UTF-16代码点, 而不是编码UTF-8字节
我怀疑“ - ”是其中一个字符,因为Ascii table中的0x96是û