zoukankan      html  css  js  c++  java
  • 计算字符串长度

    计算字符个数

    问题描述

    JavaScript中,可以通过访问字符串的length属性来获得其长度,但对于多字节字符如中文,日文和韩文等,length并不能准确地返回字符串中的字符数目。

    方法

    //Array.from(string).length;
    "".length;           //2,与预期不符
    Array.from("").length;   //1
    

    说明

    为什么使用字符串的length属性来返回字符串长度会与预期不符呢?
    这与JavaScript采用的编码方式有关。JavaScript采用的编码方式是UTF-16.
    UTF-16编码介于UTF-32与UTF-8之间,同时结合了定长和变长两种编码方法的特点。

    它的编码规则很简单:基本平面的字符占用2个字节,辅助平面的字符占用4个字节。也就是说,UTF-16的编码长度要么是2个字节(U+0000到U+FFFF),要么是4个字节(U+010000到U+10FFFF)。

    如何判断我们遇到的字符是双字节的还是4字节的并且进行正确的解读呢?这是因为在基本平面内,从U+D800到U+DFFF是一个空段,即这些码点不对应任何字符。因此,这个空段可以用来映射辅助平面的字符。

    具体来说,辅助平面可以表示220个字符,也就是说,对应这些字符至少需要20个二进制位。UTF-16将这20位拆成两半,前10位映射在U+D800到U+DBFF(空间大小210),称为高位(H),后10位映射在U+DC00到U+DFFF(空间大小210),称为低位(L)。这意味着,一个辅助平面的字符,被拆成两个基本平面的字符表示。

    所以,当我们遇到两个字节,发现它的码点在U+D800到U+DBFF之间,就可以断定,紧跟在后面的两个字节的码点,应该在U+DC00到U+DFFF之间,这四个字节必须放在一起解读。

    Unicode转换成UTF-16的计算:
    Unicode码点转成UTF-16的时候,首先区分这是基本平面字符,还是辅助平面字符。如果是前者,直接将码点转为对应的十六进制形式,长度为两字节。

    U+597D = 0x597D
    

    如果是辅助平面字符,Unicode 3.0版给出了转码公式。

    H = Math.floor((c-0x10000) / 0x400)+0xD800
    
    L = (c - 0x10000) % 0x400 + 0xDC00
    

    为什么在计算高位的时候要用c-0x10000呢?
    因为范围。Unicode的最大码元是0x10FFFF,有21位有效数字,如果不减去0x10000,就不能保证辅助平面的空间大小为220

    回到""字,《汉典》中的解释如下:

    ""的unicode码位是0x20BB7,按照上面的转换方式可以得到其UTF-16编码为:

    \uD842\uDFB7
    

    恰好是两个编码单元(16位),所以length返回的是2.
    英文字符,数字等都是16位的,但像中文等就有可能出现4个字节的码位,所以获取字符串长度的最保险的方法是:

    Array.from(string).length;
    

    感谢阅读!

    参考:

  • 相关阅读:
    HDU 4370 0 or 1 (最短路)
    POJ 2449 Remmarguts' Date (K短路 A*算法)
    HDU 5984 Pocky ( 2016 CCPC 青岛 C)
    [leetcode-733-Flood Fill]
    [leetcode-746-Min Cost Climbing Stairs]
    OpenCV学习5-----使用Mat合并多张图像
    人体姿态的相似性评价基于OpenCV实现最近邻分类KNN K-Nearest Neighbors
    OpenCV学习4-----K-Nearest Neighbors(KNN)demo
    [leetcode-728-Self Dividing Numbers]
    [leetcode-724-Find Pivot Index]
  • 原文地址:https://www.cnblogs.com/liulangbxc/p/14512902.html
Copyright © 2011-2022 走看看