2

我有一个 Unicode 字符串,例如编码为UTF8. Unicode 中的一个字符串可以有几个字节表示。我想知道,是否有或可以创建任何规范(规范化)形式的 Unicode 字符串——所以我们可以例如将这些字符串与memcmp(3)等进行比较。例如 ICU 或任何其他C/C++库可以做到这一点吗?

4

3 回答 3

6

您可能正在寻找Unicode normalization。基本上有四种不同的范式,每一种都确保所有等价的字符串之后都有一个共同的形式。但是,在许多情况下,您还需要考虑语言环境,因此虽然这可能是进行字节对字节比较的一种廉价方式(如果您确保相同的 Unicode 转换格式,如 UTF-8 或 UTF-16和相同的正常形式)除了那个有限的用例之外,它不会给你带来太多好处。

于 2012-01-23T13:15:49.150 回答
4

比较 Unicode 代码点序列:

UTF-8 本身就是一种规范的表示形式。由相同 Unicode 代码点组成的两个 Unicode 字符串将始终被编码为完全相同的 UTF-8 字节序列,因此可以与memcmp. 它是 UTF-8 编码的必要属性,否则不容易解码。但我们可以更进一步,这适用于所有官方的 Unicode 编码方案,UTF-8、UTF-16 和 UTF-32。它们将字符串编码为不同的字节序列,但它们总是将相同的字符串编码为相同的序列。如果您考虑字节序和平台独立性,则推荐使用 UTF-8 编码方案,因为您在读取或写入 16 位或 32 位值时不必处理字节顺序。

所以答案是,如果两个字符串使用相同的编码方案(例如 UTF-8)和字节序(这不是 UTF-8 的问题)进行编码,则生成的字节序列将是相同的。

比较 Unicode 字符串:

还有一个更难处理的问题。在 Unicode 中,一些字形(您在屏幕或纸上看到的字符)可以用单个代码点或两个连续代码点的组合(称为组合字符)来表示。这通常适用于带有重音符号、变音符号等的字形。由于代码点表示方式不同,它们对应的字节序列会有所不同。在考虑这些组合字符的同时比较字符串不能通过简单的字节比较来执行,首先您必须对其进行规范化。

其他答案提到了一些 Unicode 规范化技术、规范形式和库,您可以使用它们将 Unicode 字符串转换为其正常形式。然后,您将能够将它们与任何编码方案逐字节进行比较。

于 2012-01-23T13:09:59.543 回答
1

您正在寻找将字符串规范化为 Unicode 规范化形式之一。libicu 可以为您执行此操作,但不能在 UTF-8 字符串上执行此操作。您必须首先使用例如将其转换为 UChar,ucnv_toUChars然后使用 标准化unorm_normalize,然后使用ucnv_fromUChars. 我认为还有一些特定版本的 ucnv_* 用于 UTF-8 编码。

如果 memcmp 是您唯一的目标,您当然可以在unorm_normalize.

于 2012-01-23T13:16:18.217 回答