如何确定codePointAt结果的宽度?

时间:2017-08-03 05:02:05

标签: javascript unicode utf-16

我试图在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代码点的方法?

4 个答案:

答案 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;
}