我试图在Javascript字符串中循环使用Unicode字符,我假设它是用UTF-16编码的。
据我了解,UTF-16是可变宽度。也就是说,单个Unicode字符可以分成多个16位字符。我可以使用s[i].codePointAt
从给定的代码点开始获取Unicode字符。但是一旦我拥有它,我怎么知道推进我有多远?
粗略地说,getWidth
在这里是什么?它只是c > Math.pow(2, 16)
吗?
for (var i = 0; i < s.length;) {
var c = s.codePointAt(i);
// do some operation with c
i = i + getWidth(c)
}
我可以使用标准库函数来确定要前进多远吗?还是一种迭代字符串中的Unicode代码点的方法?
答案 0 :(得分:2)
是否有标准方法来迭代字符串中的Unicode代码点?
是的,因为ES6你只需要iterate所有字符串来获取代码点:
for (const character of string) {
const codepoint = character.codePointAt(0);
// do some operation with codepoint
}
答案 1 :(得分:1)
一种简单的方法:
for (var i = 0; i < s.length; ++i) {
var c = s.codePointAt(i);
// do some operation with c
if( s.charAt(i) != c) {
++i; // step past the next sixteen bits of the surrogate pair
}
(其中c
的值是Unicode代码点,而不是字符)。
如果要将字符串拆分为Unicode字符数组,可以使用ES6中引入的扩展运算符调用的字符串迭代器:
var array = [...s];
在ES6之前的浏览器中,可以识别代理对的开始,以便跳过第二部分:
for (var i = 0; i < s.length; ++i) {
var k = s.charCodeAt(i);
if( k < 0xD800 || k > 0xDBFF) {
var c = s[i]; // character in BMP
}
else {
c = s.substring( i,i+2); // use surrogate pair
++i;
}
// do something with c
console.log(c)
}
答案 2 :(得分:0)
JavaScript早于Unicode并使用另一个名为UCS2的旧系统,该系统非常相似,但不处理代理对,也不理解任何不能用两个字节表示的字符。
如果您正在查看代码点的字符串,可以查看代码点值本身...如果该值大于2 ^ 16 ,则必须提前2个字符串字符,否则提前1个字符串字符。
您可以尝试一种新的ES6 sytax,它可以很好地将字符串拆分为字符,即使这些字符是高阶的。
// High order unicode character
const k = '';
// Takes four bytes
console.log(k.length);
const chars = [...k];
// But its only one character
console.log(chars.length);
答案 3 :(得分:0)
请参阅:https://developer.mozilla.org/en-US/docs/Web/SVG/Namespaces_Crash_Course
基本上,如果您的代码点是0x010000 +,那么您正在处理多字节字符。
const MIN_SUPPLEMENTARY_CODE_POINT = 0x010000;
function charCount(int codePoint) {
return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT ? 2 : 1;
}