JavaScript | Проверка на символ алфавита человеческого языка

JavaScript | Проверка на символ алфавита человеческого языка

Как проверить, является ли символ строки буквой какого-либо алфавита любого человеческого языка?

В какой-то момент работы с регулярными выражениями появляются задачи по определению принадлежности символа строки к букве какого-то языка. Причём хочется анализировать любые строки, без акцента на какой-то конкретный язык. Ведь в современных публикациях в сети интернет легко можно встретить заголовок, который будет содержать два, а то и более, языка. Информация разрастается и с ней нужно уметь работать. И порой поисковые системы не дают правильных ответов, даже если документы встречаются в сети.

Первое, что приходит на ум разработчику, это создать «Класс Символа» по стандарту ECMAScript и пытаться по нему сопоставлять строки. Но опять же, нужно знать символы всех языков и вводить их в «Класс Символа». Это очень неудобно при ручном подходе. К счастью не нужно изобретать «велосипед» заново. Всё уже придумано и структурировано.

JavaScript плотно работает с Unicode. Unicode собирает символы со всего мира и регистрирует их в своей системе символов. В нём есть даже символы эмоций, символы устаревших языков и даже неиспользуемых языков.

Это значит, что любые символы естественного человеческого языка уже оцифрованы и имеют свои уникальные коды в стандарте Unicode. В этом наборе есть русский, английский, французский, финский … и все все остальные символы языков планеты Земля.

 

Разработчику на языке JavaScript нужно знать о возможных «Общих Значениях Категорий» (General Category Values) символов, которые описывает стандарт Unicode в документе «Unicode® Standard Annex #44Unicode Character Database (UCD)«.

Abbr Long Description
Lu Uppercase_Letter an uppercase letter
Ll Lowercase_Letter a lowercase letter
Lt Titlecase_Letter a digraphic character, with first part uppercase
LC Cased_Letter Lu | Ll | Lt
Lm Modifier_Letter a modifier letter
Lo Other_Letter other letters, including syllables and ideographs
L Letter Lu | Ll | Lt | Lm | Lo
Mn Nonspacing_Mark a nonspacing combining mark (zero advance width)
Mc Spacing_Mark a spacing combining mark (positive advance width)
Me Enclosing_Mark an enclosing combining mark
M Mark Mn | Mc | Me
Nd Decimal_Number a decimal digit
Nl Letter_Number a letterlike numeric character
No Other_Number a numeric character of other type
N Number Nd | Nl | No
Pc Connector_Punctuation a connecting punctuation mark, like a tie
Pd Dash_Punctuation a dash or hyphen punctuation mark
Ps Open_Punctuation an opening punctuation mark (of a pair)
Pe Close_Punctuation a closing punctuation mark (of a pair)
Pi Initial_Punctuation an initial quotation mark
Pf Final_Punctuation a final quotation mark
Po Other_Punctuation a punctuation mark of other type
P Punctuation Pc | Pd | Ps | Pe | Pi | Pf | Po
Sm Math_Symbol a symbol of mathematical use
Sc Currency_Symbol a currency sign
Sk Modifier_Symbol a non-letterlike modifier symbol
So Other_Symbol a symbol of other type
S Symbol Sm | Sc | Sk | So
Zs Space_Separator a space character (of various non-zero widths)
Zl Line_Separator U+2028 LINE SEPARATOR only
Zp Paragraph_Separator U+2029 PARAGRAPH SEPARATOR only
Z Separator Zs | Zl | Zp
Cc Control a C0 or C1 control code
Cf Format a format control character
Cs Surrogate a surrogate code point
Co Private_Use a private-use character
Cn Unassigned a reserved unassigned code point or a noncharacter
C Other Cc | Cf | Cs | Co | Cn

Вертикальной линией обозначены варианты категорий.

General_Category Values - Unicode
General_Category Values — Unicode

 

Для решения нашей задачи подходит категория «L» (Letter), которая обозначает все виды букв. В эту общую категорию входят буквы, которые имеют строчный вид, заглавный вид и ещё 3:

  • Lu
  • Ll
  • Lt
  • Lm
  • Lo

Теперь нужно понять как писать шаблон регулярного выражения для сопоставления. Для этого нужно обратиться к производству CharacterClassEscape.

Производство CharacterClassEscape - ECMAScript
Производство CharacterClassEscape — ECMAScript

Всего существует 8 вариантов символов для шаблона регулярного выражения, которые можно экранировать и получить дополнительную функциональность.

Для сопоставления «Любой Буквы» нас будет интересовать вариант со строчной английской «p» и фигурными скобками:

[+UnicodeMode] p{ UnicodePropertyValueExpression }

Ниже можно увидеть внутренние алгоритмы сопоставлений и принадлежностий к «General_Category«. Также в текстовом файле есть упоминание «PropertyValueAliases.txt«.

CharacterClassEscape - UnicodePropertyValueExpression - p or P - ECMAScript
CharacterClassEscape — UnicodePropertyValueExpression — p or P — ECMAScript

 

Если открыть этот файл, то можно обнаружить пометки с «gc»:

General_Category - gc - PropertyValueAliases - Unicode
General_Category — gc — PropertyValueAliases — Unicode

 

Теперь экранируем обратным слешем нашу эскейп последовательность и проверяем символы на принадлежность к буквам языка.

RegExp(/\p{L}/,'u').test('版')
true

RegExp(/\p{L}/,'u').test('?')
false

RegExp(/\p{L}/,'u').test('У')
true

RegExp(/\p{L}/,'u').test(';')
false

RegExp(/\p{L}/,'u').test('f')
true

RegExp(/\p{L}/,'u').test('0')
false

RegExp(/\p{L}/,'u').test('ب')
true

RegExp(/\p{L}/,'u').test(' ')
false

Скриншот вызовов:

Проверили символ на принадлежность к букве алфавита - JavaScript
Проверили символ на принадлежность к букве алфавита — JavaScript

 

И самая важная часть! Мы должны обязательно использовать флаг для нашего регулярного выражения. Вторым параметром мы передаём в конструктор строку с флагом «u«.

Шаблон — это либо шаблон BMP (Basic Multilingual Plane), либо шаблон Unicode, в зависимости от того, содержат ли связанные с ним флаги букву «u«. Шаблон BMP сопоставляется со строкой, интерпретируемой как состоящая из последовательности 16-битных значений, которые являются кодовыми точками Unicode в диапазоне «базовой многоязычной плоскости» (BMP).

Шаблон Unicode соответствует строке, интерпретируемой как состоящая из кодовых точек Unicode, закодированных с использованием UTF-16. В контексте описания поведения шаблона BMP «символ» означает одну 16-битную кодовую точку Unicode BMP. В контексте описания поведения шаблона Unicode «символ» означает кодовую точку в кодировке UTF-16 (6.1.4). В любом контексте «знаковое значение» означает числовое значение соответствующей незакодированной кодовой точки.

Синтаксис и семантика Pattern определяются так, как если бы исходный текст для Pattern был списком значений SourceCharacter, где каждый SourceCharacter соответствует кодовой точке Unicode. Если шаблон BMP содержит исходный символ, отличный от BMP, весь шаблон кодируется с использованием UTF-16, а отдельные кодовые единицы этой кодировки используются в качестве элементов списка.

 

Ключевые слова

JavaScript check for human alphabet character