input icon indicating copy to clipboard operation
input copied to clipboard

输入框有 emoji 表情,字数计算不对

Open MVPRubi opened this issue 3 years ago • 8 comments

image

😊 长度被计算为了 1 ,应该是 2

image

MVPRubi avatar May 11 '22 03:05 MVPRubi

麻烦帮忙确认下 🙏 @MadCcc

MVPRubi avatar May 13 '22 07:05 MVPRubi

这个存数据库的话还得看数据库编码吧,直接改可能不太合适

yunsii avatar Aug 22 '22 07:08 yunsii

const valueLength = [...val].length; 是否有必要?没必要的话去掉吧?这行代码导致的长度不对

@MadCcc M

ammikeya avatar Apr 13 '23 02:04 ammikeya

如果只考虑视觉字符长度的话,能不能使用

[...new Intl.Segmenter().segment('👩‍👩‍👧‍👦')].length  // 1

浏览器不支持就用

import runes from "runes2";

runes("👩‍👩‍👧‍👦").length  // 1

来 fallback

Jungzl avatar Apr 13 '23 03:04 Jungzl

这里的文字长度还是处理过适配 emoji 的,是逻辑不对么

MadCcc avatar May 17 '23 08:05 MadCcc

有些用户希望长度计算的是视觉上的字符个数,有些用户期待的是原生input的行为,存在两种倾向,对数据库字段长度严格要求的话理应是使用原生的行为。而期待视觉长度的用户应该是以[...new Intl.Segmenter().segment('text')].length的行为为标准,但是这个API在FF上就没实现,兼容性不行,目前有一些库比如runes2stringzgraphemer可以部分解决这个问题,不过由于实现方式不同或者历史原因没有支持新的Unicode标准都有不同程度的与Intl.Segmenter标准对不齐。

'ññநி깍字符अनुच्छेद👩‍🦰👩‍👩‍👦‍👦🏳️‍🌈🏴󠁧󠁢󠁥󠁮󠁧󠁿🏴󠁵󠁳󠁷󠁡󠁿🏴🏴󠁵󠁳󠁴󠁸󠁿󠁵󠁳󠁴󠁸󠁿Z͑ͫ̓ͪ̂ͫ̽͏̴̙̤̞͉͚̯̞̠͍A̴̵̜̰͔ͫ͗͢L̠ͨͧͩ͘G̴̻͈͍͔̹̑͗̎̅͛́Ǫ̵̹̻̝̳͂̌̌͘!͖̬̰̙̗̿̋ͥͥ̂ͣ̐́́͜͞'这个字符串为例(包含了韩文,emoji,印地语等):

str.length                                    // 165  888,877,470 ops/s
[...str].length                               // 132  1,031,108 ops/s
[...new Intl.Segmenter().segment(str)].length // 23   29,073 ops/s
runes2(str).length                            // 103  89,766 ops/s
stringz.length(str)                           // 66   82,840 ops/s
new Graphemer().countGraphemes(str)           // 24   5,628 ops/s

说到底是能否有一个标准对齐的polyfill,或者能对付大部分输入文本可能的情况(比如只多支持emoji部分,不支持合并符号)。如果提供一个flag供两种用户自行切换,维护复杂度又上去了。

Jungzl avatar May 17 '23 08:05 Jungzl

@Jungzl 理解了,这样看这个问题应该还没有一个合适的通解。 https://github.com/ant-design/ant-design/issues/42297 从这个问题上看我们应该保证 count 和 maxLength 是一致的

MadCcc avatar May 17 '23 09:05 MadCcc

统一用 runes 或 runes2 吧。

afc163 avatar May 17 '23 10:05 afc163