Unicode-свойства символов \p

Юникод, формат кодировки строк, используемый в JavaScript, имеет множество свойств для разных символов (или, технически, кодовых позиций). Они описывают к какой «категории» относится символ и прочие технические детали.

В регулярных выражениях свойства могут быть указаны с помощью \p{…}. Для таких регулярных выражений обязательно использовать флаг 'u'.

Например, \p{Letter} обозначает букву в любом языке. Также можно использовать запись \p{L}, так как L – это псевдоним Letter, существуют короткие записи почти для всех свойств.

Вот основные категории свойств:

  • Буквы L:
    • в нижнем регистре Ll, модификатор Lm, заглавные буквы Lt, в верхнем регистре Lu, прочие Lo
  • Число N:
    • десятичная цифра Nd, цифры обозначаемые буквами (римские) Nl, прочие No:
  • Знаки препинания P:
    • соединители Pc, тире Pd, открывающие кавычки Pi, закрывающие кавычки Pf, открывающие скобки Ps, закрывающие скобки Pe, прочее Po
  • Отметки M (например, акценты):
  • двоеточия Mc, вложения Me, апострофы Mn
  • Символы S:
    • валюты Sc, модификаторы Sk, математические Sm, прочие So
  • Разделители Z:
    • линия Zl, параграф Zp, пробел Zs
  • Прочие C:
    • контрольные Cc, форматирование Cf, не назначенные Cn, для приватного использования Co, суррогаты Cs.
Дополнительная информация

Хотите узнать, какие символы имеют определённое свойство? Для этого есть инструмент: http://cldr.unicode.org/unicode-utilities/list-unicodeset.

Вы также можете изучить свойства в каталоге свойств символа.

Полная база Юникод-символов в текстовом формате (вместе со всеми свойствами), находится здесь https://www.unicode.org/Public/UCD/latest/ucd/.

Есть и другие категории – производные, например:

  • Alphabetic (Alpha), включающая в себя L, плюс «буквенные цифры», обозначаемые буквами Nl (например римские цифры: Ⅻ), и некоторые другие символы Other_Alphabetic (OAltpa).
  • Hex_Digit включает символы для шестнадцатеричных чисел: 0-9, a-f. …Юникод поддерживает и много других свойств.

Например, давайте поищем шестизначные шестнадцатеричные числа:

let reg = /\p{Hex_Digit}{6}/u; // флаг 'u' -- обязательный

alert("color: #123ABC".match(reg)); // 123ABC

Существуют также свойства со значением. Например в Юникоде есть «Script» (система написания), которая может иметь значения Cyrillic (Кириллическая), Greek (Греческая), Arabic (Арабская), Han (Китайская) и так далее, полный список – длинный.

Для поиска символов в нужной системе записи (в нужном «алфавите»), мы должны установить Script=<value>, например для поиска кириллических букв: \p{sc=Cyrillic}, для китайских иероглифов: \p{sc=Han}, и так далее:

let regexp = /\p{sc=Han}+/gu; // вернёт китайские слова

let str = `Hello Привет 你好 123_456`;

alert( str.match(regexp) ); // 你好

Создание многоязычного \w

Шаблон \w предназначен для поиска «символов для слов» (words), но является всего лишь сокращением для [a-zA-Z0-9_], так что он не найдёт китайские, русские слова и т.п.

Давайте сделаем универсальный шаблон, который ищет символы, используемые в словах, для любого языка. Это очень легко с Юникод-свойствами:

/[\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}]/u

Теперь расшифруем, то что получилось. По аналогии с классом \w, который является сокращением набора [a-zA-Z0-9_], мы делаем свой набор, который включает в себя:

  • Alphabetic для букв,
  • Mark для акцентов (в Юникоде акценты могут быть представлены разными кодовыми позициями),
  • Decimal_Number для цифр,
  • Connector_Punctuation для символа '_' и подобных ему,
  • Join_Control -– две специальные кодовые позиции с кодами 200c и 200d, используемые в лигатурах, например, арабских.

Или, если заменить длинные названия псевдонимами (список псевдонимов здесь):

let regexp = /([\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]+)/gu;

let str = `Hello Привет 你好 123_456`;

alert( str.match(regexp) ); // Hello,Привет,你好,123_456
Карта учебника

Комментарии

перед тем как писать…
  • Если вам кажется, что в статье что-то не так - вместо комментария напишите на GitHub.
  • Для одной строки кода используйте тег <code>, для нескольких строк кода — тег <pre>, если больше 10 строк — ссылку на песочницу (plnkr, JSBin, codepen…)
  • Если что-то непонятно в статье — пишите, что именно и с какого места.