Если вы начнёте изучать стандарт 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.”

Комментарии (34)


  1. Kandimus
    07.11.2024 11:48

    Я не знаю никого кто использует диграф dz, все пишут две буквы. А многие сербы вообще не заморачиваются и вместо букв "c", "ć", "č" пишут "с". Такая же ситуация и с остальными буквами, где есть диакритические символы.


    1. perfect_genius
      07.11.2024 11:48

      А как dz вводится с клавиатуры? Если это сложнее, чем буквы по отдельности, то причина тогда понятна.


      1. Kandimus
        07.11.2024 11:48

        Я даже не знаю как ввести этот символ, так как на сербской клавиатуре нет такой клавиши


  1. wmlab
    07.11.2024 11:48

    Помню один из своих тасков на проекте в Польше (HR приложение) - написание функции, которая переводит юникодную строку fullname со всей этой диакриктикой и умляутами в однобитную кодировку для упрощения индексации и поиска. Сама задача простая, но пришлось долго составлять таблицу соответствий. Странно, что на такую распространенную проблему не нашлось готовой библиотечной функции.


    1. bogolt
      07.11.2024 11:48

      Гуглите по слову "Unidecode" вот например на питоне https://pypi.org/project/Unidecode/


  1. NeoCode
    07.11.2024 11:48

    А не проще ли было привести венгерский алфавит в соответствие Здравому Смыслу, а не вводить в Юникод всякую хрень? Если букву можно записать двумя буквами то это две буквы.

    А вообще где можно почитать о всяких странностях Юникода, не закапываясь в стандарт? И не приходило ли кому в голову сделать "работу над ошибками" в виде альтернативной таблицы символов (да, здесь должна быть картинка про 17 конкурирующих стандартов - но с другой стороны ведь объективно там всякой фигни накопилось немало).


    1. Goron_Dekar
      07.11.2024 11:48

      שָׁלוֹם, בּוֹקֶר טוֹב!

      (Восклицательный знак должен стоять слева, но редактор Хабра не справился с Ивритом)


      1. NeoCode
        07.11.2024 11:48

        Насколько я знаю, китайские и японские тексты исторически записываются сверху вниз, столбцами. А Юникод это не учел, непорядок! Надо ввести еще код смены направления с горизонтального на вертикальное:)


    1. LaserPro
      07.11.2024 11:48

      Если записывать звуки несколькими буквами то и получается хрень. Две, три, четыре(привет немецкому) буквы для одного звука. А всё потому что говорим мы звуками а пишем буквами. И для европейских языков очень распространён латинский алфавит, который со своим жалким набором букв не подходит ни одному более-менее популярному языку (нет он не достаточен ни для английского, ни для итальянского). Вот и приходится изображать звуки разными комбинация, умляютами, и просто дополнительными буквами. И при этом люди не хотят переходить на какой-то общий искусственный язык.


      1. NeoCode
        07.11.2024 11:48

        Не понял при чем тут звуки. Во многих языках очень нетривиальные правила чтения слов, но при чем здесь Юникод? Претензия к тому, что составители венгерского алфавита зачем-то в алфавит (который есть набор букв, атомарных символов) ввели буквосочетания, а комитет Юникода это бездумно повторил. Если в языке есть устойчивое буквосочетание, это не значит что его нужно рассматривать как отдельную букву. В английском после Q обязательно идет U, но вводить букву QU никому в голову не пришло.


        1. salnicoff
          07.11.2024 11:48

          В английском после Q обязательно идет U, но вводить букву QU никому в голову не пришло.

          Потому что есть sheqel, tzaddiq и еще много других слов, пришедших в английский из других языков.


          1. theonevolodya
            07.11.2024 11:48

            Цадик и шекель? Но они разве через q пишутся в английском?


            1. bt2901
              07.11.2024 11:48

              Iraq по-другому никогда не пишется.


            1. salnicoff
              07.11.2024 11:48

              Как один из вариантов. То, что пришло из латыни — c QU, а из идиша и французского — с Q. Потом начали менять на K для особо одаренных.


        1. LaserPro
          07.11.2024 11:48

          Вся система речи, письменности, грамматики это дремучее легаси с тысячами лет истории. Никаким новым "более лучшим и правильным" Юникодом это не исправить, всё равно будет костыль для легаси. Я за рефкторинг вместо костылей))


      1. Goron_Dekar
        07.11.2024 11:48

        Что? Чего вы говорите?

        [вдумайтесь о разнице звуков и написания этого вопроса и того, сколько звуков записано каким количеством букв]


      1. Vytian
        07.11.2024 11:48

        Потому что большинство населения мира считает фонетическое письмо глупым пережитком родоплеменного устройства общества.

        Потому что писать символы -- это не то же самое, что говорить, хуже того, местами это дополнительные, если не противоречащие задачи. Не только в матане или химии, всё программирование об этом.


        1. LaserPro
          07.11.2024 11:48

          Я уверен что большинство населения мира вообще не задумывается о таких вещах и принимает языки, письменность и алфавит как данность, что-то незыблемое и об изменении чего даже думать кощунство.


        1. perfect_genius
          07.11.2024 11:48

          писать символы -- это не то же самое, что говорить

          А как же белорусский?


      1. Stroy71
        07.11.2024 11:48

        Изучаю сейчас немецкий язык. Подскажите, какой звук обозначается 4 буквами? Пока что не встречал подобных.


        1. CaptainFlint
          07.11.2024 11:48

          tsch = ч.


        1. LaserPro
          07.11.2024 11:48

          Deutschland, Deutsche Bahn,

          И прекрасное (ок, это заимствование)

          Borschtcht

          На "Щ" уходит всего 7 букв.


          1. perfect_genius
            07.11.2024 11:48

            Borschtcht

            Похоже на нашу пиццу.


    1. CaptainFlint
      07.11.2024 11:48

      А не проще ли было привести венгерский алфавит в соответствие Здравому Смыслу, а не вводить в Юникод всякую хрень? Если букву можно записать двумя буквами то это две буквы.

      В статье же сказано: чтобы обеспечить однозначность конвертации алфавитов. Про венгерский я не знаю, а, скажем, в сербском есть буквы Њ (мягкая Н), обычная Н, и Ј (соответствующая русскому Й). В латинице эти буквы записываются как NJ, N, J. Поэтому возникает неоднозначность при переводе латиницы в кириллицу, как трактовать этот NJ: как одну букву Њ или как НЈ. И да, есть слова, где такое буквосочетание присутствует. Использование единого юникодного символа для диграфа NJ позволяет различить эти ситуации.

      По-хорошему, конечно, разработчики алфавита должны были сразу использовать неповторяющиеся буквы, скажем, ввести Ñ. Но имеем что имеем. А стандарт Юникод не диктует языкам, что они должны стать ёжиками, он лишь фиксирует существующие нормы. Хотя, конечно, на практике этими диграфами вряд ли кто-то пользуется; их даже на клавиатурах нет, насколько я знаю…


    1. Format-X22
      07.11.2024 11:48

      Как на счет русской буквы Ы? И если английская W ещё как минимум соединена визуально, то Ы уже нет. Для нас кажется нонсенсом разделить Ы на части, думаю для них dz также.


      1. kenomimi
        07.11.2024 11:48

        У нас нет буквы I в алфавите, она только в украинском есть. Потому Ы вроде как норм, дублирования в русском алфавите не происходит...


        1. CaptainFlint
          07.11.2024 11:48

          В казахском языке кириллический алфавит, в котором есть и Ь, и Ы, и І.


          1. artptr86
            07.11.2024 11:48

            В белорусском языке тоже есть Ь, Ы, I, а ещё можно упомянуть диграфы ДЖ и ДЗ, которые иногда считают отдельными буквами.


        1. bt2901
          07.11.2024 11:48

          А почему бы нам тогда не вспомнить историю буквы У, которая до Петра Первого обозначалась как диграф "оу" (Юникод сохранил следы этой традиции в символах Ꙋꙋᲈ и Ѹѹ), хотя "у" в отдельности нигде не встречалась? Почему бı нам не упростить эти странıе символı-лигатурı?

          Шутка, если что.


          1. youngmysteriouslight
            07.11.2024 11:48

            Диграфную историю «оv» мы можем наблюдать в начертаниях «y» (от второй части) и в диграфе «ю» = «iov» (от первой части).

            Кстати, «v» встречалась отдельно вплоть до начала XX в печатных гражданских (и тем более церковных) текстах (а в быту всё более заменялась на фонетические эквиваленты) в словах «мvро», «сvнодъ», «Моvсей» и прочих заимствованиях.

            Шутка, если что.

            А зря. Бездумно тащить легаси с видом, что так и должно быть, тоже не полезно.


    1. perfect_genius
      07.11.2024 11:48

      не приходило ли кому в голову сделать "работу над ошибками" в виде альтернативной таблицы символов

      Каждый раз на Хабре в статьях про странности Юникода. И я так спрашивал.

      Ещё кто-то предлагал дельную (на мой взгляд) идею: можно всё нужное поместить в 2 байта. А как же десятки тысяч иероглифов? А они состоят из общих элементов и поэтому их можно делать составными.

      Но это уже надо бы спросить китайских программистов как будет работаться с таким вариантом.


  1. TimReset
    07.11.2024 11:48

    если ввести строку поиска «mad», то она не будет соответствовать «madzag» (что означает «верёвка»), потому что «dz» в «madzag» — это отдельная буква, а не «d», за которой следует «z»

    Если кто-то решил перепроверить - нет, тут две отдельные буквы. Но в таблицах - да, один символ. :-)


  1. ris58h
    07.11.2024 11:48

    Хотел проверить везде ли автор не поленился и использовал dz в тексте (спойлер: не везде), но наткнулся на забавную особенность поиска по тексту в Chrome: при поиске по диаграфу dz он, в том числе, находит буквосочетания dz. В Firefox такого нет - поиск работает строго.


    1. perfect_genius
      07.11.2024 11:48

      Яндекс Браузер тоже находит буквосочетание, а ещё Dž.