Когда есть разница регистров, но это не верхний и не нижний регистры?
- среда, 13 ноября 2024 г. в 00:00:13
Если вы начнёте изучать стандарт Unicode, то, к своему удивлению, можете обнаружить некоторые символы, имеющие различия в регистре, при этом они сами по себе ни в верхнем, ни в нижнем регистре.
У-у-у-у, загадочно и пугающе.
Иными словами, это символ c, обладающий следующими свойствами:
toUpper(c) ≠ toLower(c), однако
c ≠ toUpper(c) и c ≠ toLower(c).
Поздравляю, вы обнаружили таинственный третий регистр: Title case.
Некоторые символы Unicode занимают одну кодовую точку, но представляют объединённые вместе два графических символа. Например, символ Unicode dz (U+01F1 LATIN SMALL LETTER DZ) выглядит как два символа Unicode, расположенных рядом друг с другом: dz (U+0064 LATIN SMALL LETTER D, за которым следует U+007A LATIN SMALL LETTER Z).
Эти диграфы — символы алфавитов некоторых языков, в частности венгерского. В таких языках диграф считается отдельной буквой алфавита. Например, вот первые десять букв венгерского алфавита¹
a | á | b | c | cs | d | dz | dzs | e | é |
Эти диграфы (и один триграф) имеют три формы.
Форма | Результат |
---|---|
Верхний регистр | DZ |
Title case | Dz |
Нижний регистр | dz |
В кодировку Unicode включено четыре диграфа.
Верхний регистр | Title case | Нижний регистр |
---|---|---|
DŽ | Dž | dž |
LJ | Lj | lj |
NJ | Nj | nj |
DZ | Dz | dz |
Но постойте, если у нас есть кодовая точка Unicode для диграфа dz, почему нет точки для диграфа cs или триграфа dzs? Что особенного в dz?
Эти диграфы обязаны своим существованием в Unicode не венгерскому, а сербохорватскому языку. Сербохорватский записывается и латиницей (хорватской), и кириллицей (сербской), и эти диграфы позволяют выполнять взаимно однозначную транслитерацию между ними¹.
Это ещё одна ситуация, в которой мир оказывается сложнее, чем мы думали. Вы думали, что поняли верхний и нижний регистр, но есть ещё один регистр между ними, о котором вы не знали.
Дополнение: то, что dz считается в венгерском одной буквой, означает, что если ввести строку поиска «mad», то она не будет соответствовать «madzag» (что означает «верёвка»), потому что «dz» в «madzag» — это отдельная буква, а не «d», за которой следует «z», аналогично тому, что «lav» не будет соответствовать слову «law» просто потому, что первая часть буквы «w» выглядит как «v». Ещё один неожиданный результат, если вы ошибочно используете литеральный поиск подстрок вместо учитывающего локаль. В следующий раз мы рассмотрим поиск подстрок с учётом локалей.
¹ Я узнал эту информацию из Unicode Standard, Version 15.0, Глава 7: “Europe I”, Section 7.1: “Latin”, подраздел “Latin Extended-B: U+0180-U+024F”, подподраздел “Croatian Digraphs Matching Serbian Cyrillic Letters.”