Ответ 1
@bobince ответ (к счастью) немного устарел; теперь вы можете просто использовать
chrs = Array.from( text )
чтобы получить список строк с одним кодовым номером, который соблюдает астральные/32bit/суррогатные символы Unicode.
Разделение строки JavaScript на "символы" можно сделать тривиально, но есть проблемы, если вы заботитесь о Unicode (и вы должны заботиться о Unicode).
JavaScript изначально обрабатывает символы как 16-битные объекты (UCS-2 или UTF-16), но это не позволяет использовать символы Unicode вне BMP (базовая многоязычная плоскость).
Чтобы обрабатывать символы Unicode за пределами BMP, JavaScript должен учитывать "суррогатные пары", которые он не делает изначально.
Я ищу, как разбить строку js на код, независимо от того, требуется ли кодовым точкам один или два символа JavaScript (единицы кода).
В зависимости от ваших потребностей расщепление codepoint может быть недостаточно, и вы можете захотеть разделить на " grapheme cluster", где кластер является базовым кодом, за которым следуют все его кодовые точки с модификатором нераспределенного интервала, такие как сочетающий акценты и диакритические знаки.
Для целей этого вопроса мне не требуется разбиение кластером графем.
@bobince ответ (к счастью) немного устарел; теперь вы можете просто использовать
chrs = Array.from( text )
чтобы получить список строк с одним кодовым номером, который соблюдает астральные/32bit/суррогатные символы Unicode.
В ECMAScript 6 вы сможете использовать строку как итератор для получения кодовых точек, или вы можете искать строку для /./ug
, или вы можете называть getCodePointAt(i)
несколько раз.
К сожалению, for
.. of
флаги синтаксиса и регулярного выражения не могут быть заполнены, а вызов полилизованного getCodePoint()
будет очень медленным (O (n²)), поэтому мы не можем реалистично использовать этот подход для пока еще.
Итак, сделайте это вручную:
String.prototype.toCodePoints= function() {
chars = [];
for (var i= 0; i<this.length; i++) {
var c1= this.charCodeAt(i);
if (c1>=0xD800 && c1<0xDC00 && i+1<this.length) {
var c2= this.charCodeAt(i+1);
if (c2>=0xDC00 && c2<0xE000) {
chars.push(0x10000 + ((c1-0xD800)<<10) + (c2-0xDC00));
i++;
continue;
}
}
chars.push(c1);
}
return chars;
}
Для обратного к нему см. fooobar.com/info/43038/...