我想要获取JavaScript字符串的长度,按照用户可见图形字符计算,即忽略组合字符(和代理对?)。是否有可能实现这一点,如果可以,如何实现?
我们在项目中使用dojo工具包,但任何通用的JavaScript解决方案都可以。
我想要获取JavaScript字符串的长度,按照用户可见图形字符计算,即忽略组合字符(和代理对?)。是否有可能实现这一点,如果可以,如何实现?
我们在项目中使用dojo工具包,但任何通用的JavaScript解决方案都可以。
以下是一款纯JavaScript库,专门用于此目的:
https://github.com/orling/grapheme-splitter
它实现了Unicode UAX-29标准,包括你可能会在自己编写解决方案时忽略的非拉丁语言重音符号、韩文jamo字符、表情符号、多个组合符号等所有边缘情况。
Intl.Segmenter
对象实现了区域敏感的文本分割,使您能够从字符串中获取有意义的项(字形、单词或句子)。
[...new Intl.Segmenter().segment('️⚧️️❤️')].length;
//=> 3
"️⚧️️❤️".length
//=> 24
[..."️⚧️️❤️"].length
//=> 17
Intl.Segmenter
在Node、Chrome和Safari中可用,但在Firefox中不可用(请查看可用性表格,这里提供了polyfill)。然后计数
let arr = [..."⛔"] // ["", "", "", "⛔", "", "", ""]
let len = arr.lenght
感谢 downGoat 的贡献。
请注意,这个解决方案在某些特殊情况下无法正常工作,例如下面的注释中一个表情符号由四个字符组成:[...""] -> ['', '', '', '', '', '', '']
尽管我将其发布在这里供 Google 搜索使用,因为对于大多数情况而言它都有效,并且比其他所有替代方案都要简单得多。
为了克服上面那种特殊的表情符号,可以搜索连接字符并进行一些修改。该字符的字符代码为8205(UTF-16)。以下是具体操作:
let myStr = ""
let arr = [...myStr]
for (i = arr.length-1; i--; i>= 0){
if (arr[i].charCodeAt(0) == 8205) { // find & handle special combination character
arr[i-1] += arr[i] + arr[i+1];
arr.splice(i, 2)
}
}
console.log(arr.length) //2
[...""] -> ['', '', '', '', '', '', '']
- Gene S关于组合字符,请查看派生组合等级,其中列出了所有的组合字符(以及其他字符)。由于您只是对计数感兴趣,您可以将它们删除——这样就能得到稍微更接近的估计。
在Angus发布的帖子中, JavaScript字符串在BMP之外显示了处理代理项的代码。但实际上,该代码执行的与您想要的相反——它将0x10000+的代码点分成两个代码点。就JS而言,它是一个代码点——虽然是截断的代码点。谁在乎呢?你在计数,而不是显示......
但是,还有另一类代码点也可能需要处理,那就是不可打印字符。当然,任何低于0x20的字符都是不可见的,但还有很多其他字符——例如查看0x2000范围。这些字符也不可见,不应计入您的计数。
这个开源的CoffeeScript实现似乎工作得相当不错:https://github.com/devongovett/grapheme-breaker(如果它不是CS的话)