在2018年使用C++处理Unicode的正确方法是什么?

The proper way to handle Unicode with C++ in 2018?

本文关键字:方法 是什么 Unicode 2018年 C++ 处理      更新时间:2023-10-16

我尝试搜索stackoverflow来找到答案,但我找到的问题和答案大约有10年的历史,由于变化和可能的进展,我似乎无法就这个主题达成共识。

我知道在 stl 之外有几个库应该处理 unicode-

  • http://userguide.icu-project.org/
  • https://github.com/nemtrif/utfcpp
  • https://github.com/CaptainCrowbar/unicorn-lib

包含stl(wstring,codecvt_utf8(的一些功能,但人们似乎对使用感到矛盾,因为他们处理的UTF-16,这个网站:(utf-8无处不在(说不应该使用,许多在线人似乎同意这个前提。

我唯一要找的是使用 unicode 字符串做 4 件事的能力-

  1. 将字符串读入内存
  2. 使用
  3. unicode 或 ascii 使用正则表达式搜索字符串,使用 ascii+unicode 数字或字符连接或对其进行文本替换/格式化。
  4. 转换为 ascii + 不适合 ascii 范围的字符的 unicode 数字格式。
  5. 将字符串写入磁盘或发送到任何地方。

据我所知,ICU处理这个问题以及更多。 我想知道的是,在Linux,Windows和MacOS上是否有处理此问题的标准方法。

谢谢你的时间。

我将尝试在这里提出一些想法:

  • 大多数C++程序/程序员只是假设文本是一个几乎不透明的字节序列。UTF-8 可能为此感到内疚,许多评论恢复到:不用担心 Unicode,只需处理 UTF-8 编码的字符串

  • 文件仅包含字节。现在,如果你尝试在内部处理真正的Unicode代码点,你将不得不将其序列化为字节->这里再次UTF-8胜

  • 一旦你走出基本的多语言平面(16位代码点(,事情就会变得越来越复杂。表情符号的处理特别糟糕:表情符号后可以跟一个变体选择器(U+FE0E 变体选择器-15 (VS15( 用于文本或 U+FE0F 变体选择器-16 (VS16( 用于表情符号样式(来改变其显示样式,或多或少是 1970 年 ascii 中使用的旧i bs ^,当时人们想要打印î。这还不是全部,字符 U+1F3FB 到 U+1F3FF 用于为 102 个人类表情符号提供肤色,分布在六个街区:丁蝙蝠、表情符号、杂项符号、杂项符号和象形文字、补充符号和象形文字,以及运输和地图符号。

    这仅仅意味着最多 3 个连续的 unicode 代码点可以表示一个字形......所以一个字符是一个char32_t的想法仍然是一个近似值

我的结论是,Unicode一件复杂的事情,确实需要像 ICU 这样的专用库。当您只处理 BMP 时,您可以尝试使用简单的工具,例如标准库的转换器,但完全支持远不止于此。


顺便说一句:即使是其他语言,如Python,假装具有本机Unicode支持(恕我直言,这比当前的C++语言要好得多(,也在某些方面失败了:

  • tkinter GUI 库无法显示 BMP 之外的任何代码点 - 而它是标准的 IDLE Python 工具
  • 除了核心语言支持(编解码器和Unicodedata(之外,不同的模块或标准库专用于Unicode,其他模块在Python Package Index中可用,例如表情符号支持,因为标准库不能满足所有需求

所以对 Unicode 的支持已经糟糕了 10 多年,我真的不希望未来 10 年情况会好得多......