在javascript中我试图将unicode转换为与C兼容的基于字节的十六进制转义序列:
即。
成为:\xF0\x9F\x98\x84
(正确)
不是javascript代理,而不是\uD83D\uDE04
(错误)
我无法弄清楚C想要的四个字节与javascript使用的两个代理之间的数学关系。我怀疑算法比我的微弱尝试复杂得多。
感谢您的任何提示。
答案 0 :(得分:1)
您的C代码需要一个UTF-8字符串(该符号表示为4个字节)。您看到的JS表示是UTF-16但是(符号表示为2 uint16
s,代理对)。
首先需要为符号(来自UTF-16 JS字符串)获取(Unicode)代码点,然后从中为它构建UTF-8表示。
从ES6开始,您可以使用codePointAt
method作为第一部分,即使不支持,我也建议将其用作垫片。我想你不想自己解码代理对:-)
对于其他人,我不认为这是一种图书馆方法,但您可以自己编写according到规范:
function hex(x) {
x = x.toString(16);
return (x.length > 2 ? "\\u0000" : "\\x00").slice(0,-x.length)+x.toUpperCase();
}
var c = "";
console.log(c.length, hex(c.charCodeAt(0))+hex(c.charCodeAt(1))); // 2, "\uD83D\uDE04"
var cp = c.codePointAt(0);
var bytes = new Uint8Array(4);
bytes[3] = 0x80 | cp & 0x3F;
bytes[2] = 0x80 | (cp >>>= 6) & 0x3F;
bytes[1] = 0x80 | (cp >>>= 6) & 0x3F;
bytes[0] = 0xF0 | (cp >>>= 6) & 0x3F;
console.log(Array.prototype.map.call(bytes, hex).join("")) // "\xf0\x9f\x98\x84"
(在Chrome中测试)
答案 1 :(得分:1)
在此处找到解决方案:http://jonisalonen.com/2012/from-utf-16-to-utf-8-in-javascript/
我从未想过那个数学,哇。
有点缩小
parentsSeq +: Seq(parent)
答案 2 :(得分:1)
docs这样做有效:
var input = "\uD83D\uDE04";
var result = encodeURIComponent(input).replace(/%/g, "\\x"); // \xF0\x9F\x98\x84
更新:实际上,C字符串可以包含数字和字母而不会转义,但是如果你真的需要转义它们:
function escape(s, escapeEverything) {
if (escapeEverything) {
s = s.replace(/[\x10-\x7f]/g, function (s) {
return "-x" + s.charCodeAt(0).toString(16).toUpperCase();
});
}
s = encodeURIComponent(s).replace(/%/g, "\\x");
if (escapeEverything) {
s = s.replace(/\-/g, "\\");
}
return s;
}