我试图得到一个javascript字符串的长度在用户可见的字形,即忽略组合字符(和代理对?)。这是可能的,如果是这样的话,我会怎么做呢?我们在我们的项目中使用dojo工具包,但是任何通用的javascript解决方案都很好。
7nbnzgx91#
下面是一个纯JavaScript库,它可以做到这一点:https://github.com/orling/grapheme-splitter它实现了Unicode UAX-29标准的所有边缘情况,你可能会错过一个自制的解决方案,如非拉丁语变音符号,韩语(韩语)jamo字符,表情符号,多个组合标记等。
cnh2zyt32#
对于组合字符,请查看Derived Combining Class,它列出了所有组合字符(以及其他字符)。在Angus链接到的帖子中,BMP之外的JavaScript字符串显示了处理代理的代码。但代码实际上与您想要的相反-它将0x10000+代码点分成两个代码点。就JS而言,它是一个代码点-尽管是截断的一个。谁在乎呢?您正在计算它们,而不是显示它们。这是一个代码点,但它是一个代码点。它是一个代码点,它是一个代码点,它是一个代码点。它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点但是,还有另一类代码点,你可能也想处理,不可打印的字符。当然,任何低于0x20的代码点,但还有很多其他的代码点-例如,看看0x2000范围。这些代码点也是不可见的,不应该包括在你的计数中。
gblwokeq3#
使用Intl.Segmenter。
Intl.Segmenter
**Intl.Segmenter**对象支持区域敏感的文本分割,使您能够从字符串中获取有意义的项目(字素,单词或句子)。
[...new Intl.Segmenter().segment('🏳️⚧️🏳️🌈👩🏾❤️👨🏻')].length; //=> 3 "🏳️⚧️🏳️🌈👩🏾❤️👨🏻".length //=> 24 [..."🏳️⚧️🏳️🌈👩🏾❤️👨🏻"].length //=> 17
截至2023年3月,Intl.Segmenter可在Node,Chrome和Safari中使用,但不适用于Firefox(see availability table,polyfill available here)。
jm2pwxwz4#
这个开源的CoffeeScript实现看起来运行得很好:https://github.com/devongovett/grapheme-breaker(如果不是CS就好了😜)
xdnvmnnf5#
那就数数
let arr = [..."😴😄😃⛔🎠🚓🚇"] // ["😴", "😄", "😃", "⛔", "🎠", "🚓", "🚇"] let len = arr.lenght
贷给downGoat
注意,在某些特殊情况下,此解决方案将不起作用,例如下面评论的一个笑脸由四个组成:[..."👩👩👧👧"] -> ['👩', '', '👩', '', '👧', '', '👧']
[..."👩👩👧👧"] -> ['👩', '', '👩', '', '👧', '', '👧']
虽然我把它贴在这里的谷歌搜索,因为在大多数情况下,它的工作,它是容易得多,然后所有其他的替代品。
为了克服上面的特殊表情符号,可以搜索连接字符并进行一些修改。此字符代码为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
还没有发现这不起作用的情况。如果您发现了,请评论
5条答案
按热度按时间7nbnzgx91#
下面是一个纯JavaScript库,它可以做到这一点:
https://github.com/orling/grapheme-splitter
它实现了Unicode UAX-29标准的所有边缘情况,你可能会错过一个自制的解决方案,如非拉丁语变音符号,韩语(韩语)jamo字符,表情符号,多个组合标记等。
cnh2zyt32#
对于组合字符,请查看Derived Combining Class,它列出了所有组合字符(以及其他字符)。
在Angus链接到的帖子中,BMP之外的JavaScript字符串显示了处理代理的代码。但代码实际上与您想要的相反-它将0x10000+代码点分成两个代码点。就JS而言,它是一个代码点-尽管是截断的一个。谁在乎呢?您正在计算它们,而不是显示它们。这是一个代码点,但它是一个代码点。它是一个代码点,它是一个代码点,它是一个代码点。它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点,它是一个代码点
但是,还有另一类代码点,你可能也想处理,不可打印的字符。当然,任何低于0x20的代码点,但还有很多其他的代码点-例如,看看0x2000范围。这些代码点也是不可见的,不应该包括在你的计数中。
gblwokeq3#
使用
Intl.Segmenter
。**
Intl.Segmenter
**对象支持区域敏感的文本分割,使您能够从字符串中获取有意义的项目(字素,单词或句子)。截至2023年3月,
Intl.Segmenter
可在Node,Chrome和Safari中使用,但不适用于Firefox(see availability table,polyfill available here)。jm2pwxwz4#
这个开源的CoffeeScript实现看起来运行得很好:https://github.com/devongovett/grapheme-breaker(如果不是CS就好了😜)
xdnvmnnf5#
拆分字符串到数组
那就数数
贷给downGoat
注意,在某些特殊情况下,此解决方案将不起作用,例如下面评论的一个笑脸由四个组成:
[..."👩👩👧👧"] -> ['👩', '', '👩', '', '👧', '', '👧']
虽然我把它贴在这里的谷歌搜索,因为在大多数情况下,它的工作,它是容易得多,然后所有其他的替代品。
完整解决方案
为了克服上面的特殊表情符号,可以搜索连接字符并进行一些修改。此字符代码为8205(UTF-16)。下面是如何做到这一点:
还没有发现这不起作用的情况。如果您发现了,请评论