Javascript Regex + Unicode Diacritic Объединение символов`

Я хочу сопоставить этот символ на африканском языке йоруба 'ẹ́'. Обычно это делается путем сочетания «é» с «\ u0323» под диакритической точкой. Я нашел это:

'é\u0323'.match(/[é]\u0323/) works but
'ẹ́'.match(/[é]\u0323/) does not work.

Я не просто хочу соответствовать e. Я хочу соответствовать всем комбинациям. Прямо сейчас мое решение включает в себя перечисление всех комбинаций. Вот так: /[ÁÀĀÉÈĒẸE̩Ẹ́É̩Ẹ̀È̩Ẹ̄Ē̩ÍÌĪÓÒŌỌO̩Ọ́Ó̩Ọ̀Ò̩Ọ̄Ō̩ÚÙŪṢS̩áàāéèēẹe̩ẹ́é̩ẹ̀è̩ẹ̄ē̩íìīóòōọo̩ọ́ó̩ọ̀ò̩ọ̄ō̩úùūṣs̩]/

Не может ли быть более короткого и, следовательно, лучшего способа сделать это, или сопоставление регулярных выражений в javascript с диакритическими знаками Unicode, объединяющими символы, не работает так легко? Спасибо


person user2530580    schedule 28.06.2013    source источник
comment
Если честно, я бы предпочел прочитать и сохранить эту короткую строку символов, чем расшифровать и понять часть \uxxxx возможно более умного регулярного выражения. Использование таблицы поиска всегда будет быстрее, чем сначала вычисление char. Возможный способ, если регулярное выражение не работает, - отобразить символ в диапазоне, а затем сравнить   -  person mplungjan    schedule 28.06.2013
comment
Неплохо подмечено. Возможно, текущий способ лучше.   -  person user2530580    schedule 28.06.2013
comment
В итоге я остановился на части \uxxxx, потому что ее редактирование в vim имело гораздо больше смысла, когда повсюду не было точек юникода разной ширины с разными направлениями потока, которые делали с позицией курсора совершенно замечательные вещи: его позиция в основном становилась случайной величиной.   -  person user2530580    schedule 28.04.2015


Ответы (2)


Обычно это делается путем сочетания буквы «é» с «\ u0323» под диакритической точкой.

Однако это не то, что у вас здесь:

'ẹ́'

это не U+0065,U+0323, а U+1EB9,U+0301 — сочетание с острым диакритическим знаком.

Обычное решение состоит в том, чтобы нормализовать каждую строку (обычно в Unicode Normal Form C) перед выполнением сравнения.

Я не просто хочу соответствовать e. Я хочу сопоставить все комбинации

Сопоставление без диакритических знаков обычно выполняется путем нормализации к нормальной форме D и удаления всех сочетающихся диакритических знаков.

К сожалению, нормализация недоступна в JS, поэтому, если вы хотите, вам придется перетаскивать код, чтобы сделать это, который должен включать большую таблицу данных Unicode. Одним из таких усилий является unorm. Для подбора символов на основе предварительных свойств Unicode, таких как комбинирование диакритических знаков, вам также понадобится механизм регулярных выражений с поддержкой базы данных Unicode, например Категории Юникода XRegExp.

Серверные языки (например, Python, .NET) обычно имеют встроенную поддержку нормализации Unicode, поэтому, если вы можете выполнять обработку на сервере, это обычно проще.

person bobince    schedule 28.06.2013
comment
Это объясняет это. Спасибо - person user2530580; 28.06.2013
comment
bobince, когда у вас будет минутка, вы можете обновить это, чтобы ссылаться на ES6 .normalize. - person Sergio; 21.08.2016

Обычно решением является использование свойств Unicode и/или скриптов, но JavaScript не поддерживает их изначально.

Но существует библиотека XRegExp, которая добавляет эту поддержку. С этой библиотекой вы можете использовать

\p{L}: соответствует любой букве любого языка.

\p{M}: символ, предназначенный для комбинирования с другим символом (например, акценты, умлауты, закрывающие прямоугольники и т. д.).

Таким образом, ваш класс персонажа будет выглядеть так:

[\p{L}\p{M}]+

это будет соответствовать всем возможным буквам, которые есть в таблице Unicode.

Если вы хотите ограничить его, вы можете просмотреть скрипты Unicode и заменить \p{L} скриптом, они собирают все буквы с определенных языков. например \p{Latin} для всех латинских букв или \p{Cyrillic} для всех кириллических букв.

person stema    schedule 28.06.2013