【发布时间】:2011-07-30 20:45:03
【问题描述】:
我正在开发一个 twitter 应用程序,并且偶然发现了 utf-8(16) 的世界。似乎大多数 javascript 字符串函数都像我一样对代理对视而不见。我必须重新编码一些东西以使其具有宽字符意识。
我有这个函数可以将字符串解析为数组,同时保留代理对。然后我将重新编写几个函数来处理数组而不是字符串。
function sortSurrogates(str){
var cp = []; // array to hold code points
while(str.length){ // loop till we've done the whole string
if(/[\uD800-\uDFFF]/.test(str.substr(0,1))){ // test the first character
// High surrogate found low surrogate follows
cp.push(str.substr(0,2)); // push the two onto array
str = str.substr(2); // clip the two off the string
}else{ // else BMP code point
cp.push(str.substr(0,1)); // push one onto array
str = str.substr(1); // clip one from string
}
} // loop
return cp; // return the array
}
我的问题是,我还缺少什么更简单的东西吗?我看到很多人重申 javascript 原生处理 utf-16,但我的测试让我相信,这可能是数据格式,但函数还不知道。我错过了一些简单的东西吗?
编辑: 为了帮助说明问题:
var a = "0123456789"; // U+0030 - U+0039 2 bytes each
var b = "????????????????????????????????????????"; // U+1D7D8 - U+1D7E1 4 bytes each
alert(a.length); // javascript shows 10
alert(b.length); // javascript shows 20
Twitter 将这两个字符都视为 10 个字符。
【问题讨论】:
-
你实际上需要做什么?
-
基本操作。 Twitter 不返回内联链接,只返回纯文本和 url 以及 url 所属位置的索引。索引基于代码点而不是 16 位字符。我还有一个用于格式化推文的文本区域。 Javascript 将简单的字符计数视为 16 位大块的计数,而不是单个代码点。我可以解决,只是不想在不询问专业人士是否有更简单的事情的情况下就走错方向。
-
Javascript 在内部使用 UCS-2,不是 UTF-16。因此在 Javascript 中处理 Unicode 非常困难,并且我不建议尝试这样做。至于 Twitter 做什么,您似乎是在说它是按代码点而不是按代码单元疯狂计数。
-
@tchrist:你这是什么意思?对开发人员可见的 JavaScript 字符串是 UTF-16 编码的。
-
@Tim 它们显示为单独代码单元的 UCS-2 字符串,而不是代码点的 Unicode 字符串。您可以使用正则表达式向自己证明这一点。试着在一个模式中写
[????-????],看看会发生什么。它只是坏了。如果 Javascript 实际使用 UTF-16,我将能够编写document.write(String.fromCharCode(0x1D49C))并且不必编写 也不允许编写document.write(String.fromCharCode(0xD835,0xDC9C))代替它。这是破坏 UCS-2 的废话。
标签: javascript string unicode twitter utf-16