如何在 C++ 中实现与 unicode 无关的不区分大小写的比较

Mad*_*ddy 0 c++ string unicode case-insensitive icu

我有一个要求,其中我的 C++ 代码需要进行不区分大小写的比较,而不必担心字符串是否已编码,或者所涉及的编码类型。该字符串可以是 ASCII 或非 ASCII,我只需要按原样存储它并将其与第二个字符串进行比较,而无需考虑是否设置了正确的语言环境等等。

用例:假设我的应用程序接收一个字符串(假设它是一个文件名)最初为“Zoë Saldaña.txt”,并按原样存储它。随后,它接收另一个字符串“zoë saLdañA.txt”,并且通过使用一些 API,该字符串与第一个字符串之间的比较应该会导致匹配。与文件名“abc.txt”和“AbC.txt”相同。

我阅读了 IBM 的 ICU 以及它默认如何使用 UTF-16 编码。我很想知道:

  1. 如果 ICU 提供了一种通过无缝处理字符串来解决我的需求的方法,而不管它们的编码类型如何?

  2. 如果 1. 的答案是否定的,那么,使用 ICU 的 API,将所有字符串(ASCII 和非 ASCII)规范化为 UTF-16,然后进行不区分大小写的比较和其他操作是否安全?

  3. 是否有替代方案可以促进这一点?

我读了这篇文章,但它不太符合我的要求。

谢谢!

MSa*_*ers 5

要求是不可能的。计算机不处理字符,它们处理数字。但是“不区分大小写”的比较是对字符起作用的操作。区域设置决定了哪些数字对应哪些字符,因此是必不可少的。

以上不仅适用于所有编程语言,甚至适用于区分大小写的比较。从字符到数字的映射并不总是唯一的。这意味着比较两个数字不起作用。可能存在字符 42 等同于字符 43 的语言环境。在 Unicode 中,情况更糟。有些数字序列 具有不同的长度,但仍然是等价的。(特别是预组合和分解字符)

  • Unicode 太可怕了,简直是一场彻头彻尾的噩梦。真正可怕的是它比以前的任何东西都要好得多。 (4认同)
  • @MartinBonner:嗯,大约 6000 种语言(忽略方言)使用单一编码是一个挑战。也就是说,理论上你可以引入“Unicode Light”,而不需要像表情符号这样完全愚蠢的东西,但代价是什么? (2认同)
  • 表情符号根本没有问题(它们只是“字符”)。类似“拉丁文大写字母 A 上面有环”和“拉丁文大写字母 A”+“组合上面的环”(不要忘记“ANGSTROM SIGN”)之类的东西,我认为这是一场噩梦。(以及“LATIN CAPITAL LETTER A”+“COMBINING RING ABOVE”+“COMBINING CEDILA”应该如何比较等于“LATIN CAPITAL LETTER A”+“COMBINING CEDILA”+“COMBINING RING ABOVE”)。但真正的困难是真正的语言很复杂:我最喜欢的例子是德语中“MASS”的小写版本是“Maß”或“Mass”,具体取决于它是什么词。 (2认同)
  • 是的,我确实让“M”大写。 (2认同)
  • @Maddy:将两个字符串加载到 ICU 中进行比较,告诉 ICU 在读取两个字符串时使用什么编码,并让 ICU 比较两个_而不用担心 ICU 的内部编码_。任何 Unicode 编码都可以,无论是 UTF-8、UTF-16 还是 UTF-32。ICU 都了解这些。 (2认同)