Ааа́Ббб́Ввв́Г㥴Дд
我想按字符拆分它。目前,如果我尝试循环遍历所有字符,我会得到类似这样的结果:
A a a ' Б ...
有没有一种正确的方法将此字符串拆分为字符:А а а́
?Ааа́Ббб́Ввв́Г㥴Дд
我想按字符拆分它。目前,如果我尝试循环遍历所有字符,我会得到类似这样的结果:
A a a ' Б ...
有没有一种正确的方法将此字符串拆分为字符:А а а́
?function findGraphemesNotVeryWell(s) {
var re= /.[\u0300-\u036F]*/g;
var match, matches= [];
while (match= re.exec(s))
matches.push(match[0]);
return matches;
}
findGraphemesNotVeryWell('Ааа́Ббб́Ввв́Г㥴Дд');
["А", "а", "а́", "Б", "б", "б́", "В", "в", "в́", "Г", "г", "Ґ", "ґ", "Д", "д"]
(*: 也许可以通过让浏览器呈现字符串并测量其选择位置的方法来提取信息...但这肯定会非常混乱和难以在各种浏览器中运行。)
关于这个问题的最新更新。
随着ES6的到来,有了新的字符串方法和处理字符串的方式。 这里有两个问题的解决方案。
表情符号和其他Unicode字符位于基本多语言平面(BMP)以上(范围在Unicode“代码点”0x0000 - 0xFFFF
之外),可以像ES6中的字符串一样遵循迭代器协议进行处理,因此可以这样做:
let textWithEmoji = '\ud83d\udc0e\ud83d\udc71\u2764'; //horse, happy face and heart
[...textWithEmoji].length //3
for (char of textWithEmoji) { console.log(char) } //will log 3 chars
随着您开始处理“字形簇”(一个字符及其变音符号),这将是一个更难解决的问题。在ES6中,有一种方法可以简化处理此类问题,但仍然很难操作。 String.prototype.normalize
方法可以简化工作,但正如Mathias Bynens所说:
(A)对于带有多个组合标记的代码点始终会产生单个可视字形,但可能没有规范化的形式,在这种情况下,规范化无效。
更多见解可以在以下链接中找到:
https://ponyfoo.com/articles/es6-strings-and-unicode-in-depth https://mathiasbynens.be/notes/javascript-unicode
Array.from
。 - ygormutti[..."❤"].length
却是3,太棒了。 - WSBT这个包可能会对您有所帮助:https://www.npmjs.com/package/runes
const runes = require('runes')
const example = 'Emoji '
example.split('') // ["E", "m", "o", "j", "i", " ", "�", "�"]
runes(example) // ["E", "m", "o", "j", "i", " ", ""]
utf8-stream
进行管道传输以防止这种情况:
使用Unicode属性Grapheme_Base
"Ааа́Ббб́Ввв́Г㥴Дд".match(/\p{Grapheme_Base}/gu)
> ['А', 'а', 'а', 'Б', 'б', 'б', 'В', 'в', 'в', 'Г', 'г', 'Ґ', 'ґ', 'Д', 'д']
"Ааа́Ббб́Ввв́Г㥴Дд".match(/\p{Grapheme_Extend}/gu)
> ['́', '́', '́']
"Ааа́Ббб́Ввв́Г㥴Дд".match(/\p{Grapheme_Base}\p{Grapheme_Extend}|\p{Grapheme_Base}/gu)
> ['А', 'а', 'а́', 'Б', 'б', 'б́', 'В', 'в', 'в́', 'Г', 'г', 'Ґ', 'ґ', 'Д', 'д']
"אַּׁ".match(/\p{Grapheme_Base}/gu)
,除了 "אַּׁ".match(/\p{Grapheme_Extend}/gu)
之外,你会得到匹配结果。后者是 ['ׁ', 'ּ', 'ַ']。不确定为什么你的星号(*)无法工作。这是什么语言? - Clemens Tolboom"אַּׁ".match(/\p{Grapheme_Extend}/gu)
之外还使用 "אַּׁ".match(/\p{Grapheme_Base}/gu)
,你会得到匹配结果。后者是 ['ׁ', 'ּ', 'ַ']。不确定为什么你的 */星号没有起作用。这是什么语言? - Clemens Tolboom你的字符串问题在于它包含了代理对("a" "́),只有在浏览器显示时才会组合成单个字符。对于你的情况,如果你将\u0301附加到前一个字符上就足够了,但这绝不是一般解决方案。
var a="Ааа́Ббб́Ввв́Г㥴Дд",
i =0,
chars=[];
while(a.charAt(i)) {
if (a.charAt(i+1) == "\u0301") {
chars.push(a.charAt(i++)+a.charAt(i++));
} else {
chars.push(a.charAt(i++));}}
为了澄清问题,请前往阅读Mathias Bynens的博客文章。
a.fromCharCode(i)
,真的吗?——它不支持组合,所以你又回到了起点... - ddacharCodeAt(index)
在UTF-16代码单元方面工作吗?所以对于BMP之外的任何内容都不起作用。 - bames53chars
数组。 - Aleš Kotnikchars
数组仍然返回每个单独的字符,而不是将 "а" + "́" === "а́"
组合起来。 - Gapipro
for..of
使用String.prototype[Symbol.iterator]
,它按代码点步长进行迭代(有时超过一个字符长度),而使用方括号进行索引则不会。 - ygormutti