Получить количество символов графемы в строках JavaScript?

Я пытаюсь получить длину строки javascript в видимых пользователем графемах, то есть игнорируя объединение символов (и суррогатных пар?). Возможно ли это, и если да, то как мне это сделать?

Мы используем инструментарий dojo в нашем проекте, но любое общее решение javascript было бы замечательно.

5 ответов

Решение

Для комбинирующих символов посмотрите на класс производных комбинаций, в котором перечислены все комбинируемые символы (среди прочих). Поскольку вы просто заинтересованы в подсчете, вы можете просто убить их, оставив немного более точную оценку.

В посте, связанном с Angus, строки JavaScript за пределами BMP показывают код для работы с суррогатами. Но код на самом деле противоречит тому, что вы хотите - он разбивает кодовые точки 0x10000+ на две кодовые точки. Что касается JS, то это одна кодовая точка - хотя и усеченная. Какая разница? Ты их считаешь, а не показываешь...

НО, есть еще одна категория кодовых точек, с которыми вы тоже можете иметь дело, непечатные символы. Конечно, все что угодно под 0x20, но есть много других - посмотрите, например, на диапазон 0x2000. Они также не видны и не должны быть включены в ваш счет.

Использовать.

The object включает сегментацию текста с учетом локали, позволяя вам получать значимые элементы (графемы, слова или предложения) из строки.

      [...new Intl.Segmenter().segment('️‍⚧️️‍‍❤️‍')].length;
//=> 3

"️‍⚧️️‍‍❤️‍".length
//=> 24

[..."️‍⚧️️‍‍❤️‍"].length
//=> 17

По состоянию на июль 2022 г.Intl.Segmenterдоступен в Node, Chrome и Safari, но не в Firefox.

Вот чистая библиотека JavaScript, которая делает именно это:

https://github.com/orling/grapheme-splitter

Он реализует стандарт Unicode UAX-29 во всех своих крайних случаях, которые вы, скорее всего, пропустите в домашнем пивоварении, например, нелатинские диакритические знаки, хангул (корейский) символы джамо, смайлики, множественные комбинированные метки и т. Д.

Разделить строку на массив

Затем посчитайте

      let arr = [..."⛔"] // ["", "", "", "⛔", "", "", ""]
let len = arr.lenght

Кредит на downGoat

Обратите внимание , что это решение не будет работать в некоторых особых случаях, например, в приведенных ниже комментариях, когда один смайлик состоит из четырех: [..."‍‍‍"] -> ['', '‍', '', '‍', '', '‍', '']

Хотя я разместил его здесь для поиска Google, так как в большинстве случаев это работает, и это намного проще, чем все другие альтернативы.

Эта реализация CoffeeScript с открытым исходным кодом, кажется, работает достаточно прилично: https://github.com/devongovett/grapheme-breaker (если только это не CS)

Другие вопросы по тегам