长期以来,我们在JS中使用天真的方法来分割字符串:
someString.split('');
但是,emoji表情的普及迫使我们改变了这种方法- 像😀这样的emoji字符(以及其他非BMP字符)由两个“字符”组成。
String.fromCodePoint(128514).split(''); // array of 2 characters; can't embed due to StackOverflow limitations
那么,现代、正确和高效的方法是什么呢?
长期以来,我们在JS中使用天真的方法来分割字符串:
someString.split('');
但是,emoji表情的普及迫使我们改变了这种方法- 像😀这样的emoji字符(以及其他非BMP字符)由两个“字符”组成。
String.fromCodePoint(128514).split(''); // array of 2 characters; can't embed due to StackOverflow limitations
那么,现代、正确和高效的方法是什么呢?
const str = "";
console.log([...str]);
function split(str){
const arr = [];
for(const char of str)
arr.push(char)
return arr;
}
const str = "";
console.log(split(str));
[...'♀️']
变成 ["", "", "", "♀", "️"]
。这意味着无法进行简单的字符串反转或逐个符号比较等操作。 - AndyO这项任务的最佳方法是使用本地化的 String.prototype[Symbol.iterator]
,它能识别Unicode字符。因此,在字符串上使用Array.from
是分割Unicode字符的一种简洁易行的方法,例如:
const string = String.fromCodePoint(128514, 32, 105, 32, 102, 101, 101, 108, 32, 128514, 32, 97, 109, 97, 122, 105, 110, 128514);
Array.from(string);
[...'♀️']
变为 ["", "", "", "♀", "️"]
。 - srghmaJavaScript新增了一个API(作为ES2023的一部分),称为Intl.Segmenter
,它允许您基于字形(字符串的用户感知字符)拆分字符串。 使用此API,您的拆分可能如下所示:
const split = (str) => {
const itr = new Intl.Segmenter("en", {granularity: 'grapheme'}).segment(str);
return Array.from(itr, ({segment}) => segment);
}
// See browser console for output
console.log(split('')); // ['']
console.log(split('é')); // ['é']
console.log(split('')); // ['']
console.log(split('❤️')); // ['❤️']
console.log(split('♀️')); // ['♀️']
<p>See browser console for logs</p>
这使您不仅可以处理由两个代码点构成的表情符号,例如,还包括其他字符,例如组合字符(例如
é
),由ZWJ分隔的字符(例如
),带有变量选择器的字符(例如❤️),带有表情符号修饰符的字符(例如♀️
)等,所有这些字符都不能通过调用字符串迭代器(使用展开运算符...
,for..of
,Symbol.iterator
等)来处理,如其他答案中所述,因为这些方法只会迭代字符串的代码点。
在ECMA 2015中引入了一个标志来支持正则表达式的Unicode感知。
将u
添加到您的正则表达式中,可以返回完整的字符作为您的结果。
const withFlag = `ABDE`.match(/./ug);
const withoutFlag = `ABDE`.match(/./g);
console.log(withFlag, withoutFlag);
关于它,这里有更多信息
'♀️'.match(/./ug)
将变成 ["", "", "", "♀", "️"]
。 - srghma我曾在某个地方做过类似的事情,需要支持旧版浏览器和ES5缩小器,这可能对其他人有用。
if (Array.from && window.Symbol && window.Symbol.iterator) {
array = Array.from(input[window.Symbol.iterator]());
} else {
array = ...; // maybe `input.split('');` as fallback if it doesn't matter
}
JSON.stringify(String.fromCodePoint(128514).split(''))
结果表达式的问题 - 这会导致jQuery抛出“格式不正确的URI”错误并禁止发布问题。 - Ginden