JavaScript剪切字符串且不拆分表情符号

13

在我的JavaScript中,我试图使用substring()函数截取文本,这通常可以实现,但不幸的是会切断表情符号。

usaText = "AZ"
splitText = usaText.substring(0,2) //"A�"
splitText = usaText.substring(0,3) //"A"
splitText = usaText.substring(0,4) //"A�"
splitText = usaText.substring(0,5) //"A"

有没有一种方法可以使用子字符串而不会中断表情符号?在我的生产代码中,我通常在大约40个字符处截断,如果它是35或45也无妨。我曾考虑过简单地检查第40个字符是否为数字或介于a-z之间,但如果你得到一个充满表情符号的文本,这种方法就行不通了。我可以通过模式匹配检查最后一个字符是否是“结束”表情符号,但在性能方面似乎也有些奇怪。

我错过了什么吗?在JavaScript所携带的所有膨胀中,难道没有内置的count将表情符号视为一个吗?

关于将JavaScript字符串拆分为代码点数组?(考虑到“代理对”但不是“字形群集”)的事情:

chrs = Array.from( usaText )
(4) ["A", "", "", "Z"]
0: "A"
1: ""
2: ""
3: "Z"
length: 4

很遗憾,这一个太多了。


你可以考虑查找表情符号,记录它们的位置,然后将其删除。然后进行子字符串操作,根据原始字符串中的位置将表情符号放入子字符串中。子字符串的长度将不再相同,但你说这不是问题。 - RobG
3
请忘记“emoji”,你所问的是代理对UTF-16,它同样适用于普通语言和表情符号。这个问题已经有一个优雅的解决方案了,可以在https://dev59.com/jGEi5IYBdhLWcg3wUa46上找到答案。使用`Array.from(yourstring)`即可将字符串拆分为单个Unicode字符,而不会在字节之间断开它们。 - Mike 'Pomax' Kamermans
请检查我的代码。我已经尝试过了,虽然它让我的情况有所改善,但仍然存在2个部分问题。 - user2875404
3个回答

12

所以这并不是一件容易的事情,我倾向于告诉你不应该自己写。你应该使用像runes这样的库。

只需要简单的npm i runes,然后:

const runes = require('runes');
const usaText = "AZ";
runes.substr(usaText, 0, 2); // "A"

2
符文代码也是足够简单的,因此它非常适合作为重要字形群集分割问题的入门。我强烈推荐阅读代码和测试案例。https://github.com/dotcypress/runes/blob/develop/index.js - Rob Napier
2
runes(usaText) -> (3) ["A", "", "Z"]。非常好,谢谢! - user2875404

3

2
这段代码对我很有效:
splitText = Array.from(usaText).slice(0, 5).join('');

欢迎来到stackoverflow。除了您提供的答案外,请考虑提供一个简要的解释,说明为什么以及如何解决这个问题。 - jtate
2
嘿,你代码中的(0, 2)结果是A。通常情况下,人们要么完全包含表情符号,要么不包含 - 而不是得到破碎的分数。 - user2875404
这是正确的答案。不确定为什么它不是绿色的。 - Tengiz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接