Правильный способ обработки Unicode с C++ в 2018 году?

Я попытался найти stackoverflow, чтобы найти ответ на этот вопрос, но вопросы и ответы, которые я нашел, составляют около 10 лет, и я не могу найти консенсуса по этому вопросу из-за изменений и возможного прогресса.

Есть несколько библиотек, которые мне известны за пределами stl, которые должны обрабатывать unicode-

Есть несколько особенностей stl (wstring, codecvt_utf8), которые были включены, но люди, как представляется, неоднозначны в использовании, потому что они имеют дело с UTF-16, которые этот сайт: (utf-8 везде) не должны использоваться, и многие люди онлайн, похоже, согласны с предпосылкой.

Единственное, что я ищу, это способность делать 4 вещи с помощью unicode strings-

  1. Чтение строки в память
  2. Найдите строку с регулярным выражением, используя unicode или ascii, объедините или замените/форматируйте текст с помощью либо символов ascii + unicode, либо символов.
  3. Преобразуйте в ascii + формат номера юникода для символов, которые не соответствуют диапазону ascii.
  4. Напишите строку на диск или отправьте где угодно.

Из того, что я могу сказать, icu обрабатывает это и многое другое. Я хотел бы знать, есть ли стандартный способ обработки этого в Linux, Windows и MacOS.

Спасибо за ваше время.

Ответ 1

Здесь я попытаюсь бросить некоторые идеи:

  • большинство C++ программ/программистов просто предполагают, что текст представляет собой почти непрозрачную последовательность байтов. UTF-8, вероятно, виноват в этом, и нет ничего удивительного в том, что многие комментарии возобновляются: не волнуйтесь с Unicode, просто обрабатывайте кодированные строки UTF-8
  • файлы содержат только байты. В какой-то момент, если вы попытаетесь внутренне обработать истинные коды кода Unicode, вам придется сериализовать это значение в байтах → здесь снова UTF-8 выигрывает точку
  • как только вы выходите из базовой многоязычной плоскости (16-битные кодовые точки), все становится все более сложным. Эможи особенно ужасны для обработки: за эмулятором может следовать селектор вариаций (U + FE0E VARIATION SELECTOR-15 (VS15) для текста или U + FE0F VARIATION SELECTOR-16 (VS16) для стиля emoji), чтобы изменить его отображение стиль, более или менее старые i bs ^, который был использован в 1970 году, когда один ASCII хотел напечатать î. Это не все, символы U + 1F3FB до U + 1F3FF используются для обеспечения цвета кожи для 102 человеческих эмози, распространяющихся по шести блокам: дингбаты, смайлики, различные символы, различные символы и пиктограммы, дополнительные символы и пиктограммы, а также транспорт и карта Символы.

    Это просто означает, что до трех последовательных кодовых точек юникода может представлять один единственный символ... Итак, идея о том, что один символ является одним char32_t, все еще является приближением

Я пришел к выводу, что Unicode - сложная вещь, и на самом деле требуется специальная библиотека, такая как ICU. Вы можете попробовать использовать простые инструменты, такие как конвертеры стандартной библиотеки, когда имеете дело только с BMP, но полная поддержка далеко за пределами этого.


BTW: даже другие языки, такие как Python, которые притворяются, что имеют поддержку родного юникода (что ИМХО намного лучше, чем текущий C++), терпит неудачу в некоторой части:

  • библиотека GUI tkinter не может отображать любую точку кода вне BMP - в то время как это стандартный инструмент IDLE Python
  • различные модули или стандартная библиотека предназначены для Unicode в дополнение к поддержке основного языка (кодеки и уникодательные файлы), а другие модули доступны в Индексе пакетов Python, например, поддержка emoji, поскольку стандартная библиотека не отвечает всем потребностям

Так что поддержка Unicode бедна уже более 10 лет, и я не очень надеюсь, что в ближайшие 10 лет все будет намного лучше...