错误的unicode字符串,看起来一样,但本质不一样



Eror文本unicode

当我使用CURL获取网站内容时,我获得的内容看起来是一样的,但实际情况不同。这会影响文件的处理和比较。有没有一种方法可以将$loi转换为$check标准表单,这样我就可以正确处理它?

您可以将内容$loi或$check复制到cmd窗口中,立即查看图片中所示的差异

$loi = 'người được tiêm';
$check = 'người được tiêm';
var_dump($loi);
var_dump($check);

有些代码点在Unicode中看起来是相同的,因为它们具有相似甚至相同的字形,但实际上是而不是

当你意识到Unicode的目的是容纳尽可能多的语言时,这就不足为奇了,它通常表示字母的目的,而不是形式。

例如,U+2010U+2011(连字符和不间断的hyphemn(看起来可能完全相同,因为后者只是前者的不间断版本。

如果您将两个字符串输入到Unicode到代码点的转换器中,您将看到差异。

为了简洁起见,我只做了每个单词的第一个单词,并用十六进制给出了代码点,每个"周围都有方括号;字符":

người [6e] [67] [75 31b] [6f 31b 300] [69]
người [6e] [67] [1b0]    [1edd]       [69]

例如,第一个中的75 31b,它是Latin small letter U,后面跟着combining horn(字母的修饰符(。在第二个中,它是单个1b0Latin small letter U with horn(已经内置到代码点的修饰符(。

类似地,ờ是第一个中的6f 31b 300,三个独立的代码点表示Latin small letter Ocombining horn修饰符和combining grave accent修饰符。第二个是1edd,两个修饰符都已合并到单个代码点Latin small letter O with horn and grave中。

因此,在这些情况下,它实际上与字形没有什么不同,但它是一种不同的表示方式:

  • 内置修饰符的单个代码点;或
  • 具有单独的附加修饰符代码点的代码点

如果您需要将它们视为相同的,Unicode有一个等价和规范化的概念。

等价性表示多个码点序列,它们实际上是同一"码"的变体;事物";,归一化是将等价物映射到单个变体的过程,这样比较更容易。

在Python中,我会使用以下方法进行映射:

import unicodedata
normalised_composed = unicodedata.normalize('NFC', 'người'))
normalised_decomposed = unicodedata.normalize('NFD', 'người'))
# Composed is short sequence (minimal codepoints), decomposed is long.

下面的文字记录显示了输出,尽管为了可读性,我已经重新格式化并注释了:

>>> bytearray('người', 'utf-16')
bytearray(b'xffxfe                # Unicode BOM for UTF-16.
nx00                           # n.
gx00                           # g.
ux00 x1bx03                  # u, combining horn.
ox00 x1bx03 x00x03         # o, combining horn & grave.
ix00                           # i.
')
>>> bytearray(unicodedata.normalize('NFD', 'người'), 'utf-16')
bytearray(b'xffxfe                # Identical to previous, it
nx00                           #   was already decomposed.
gx00
ux00 x1bx03
ox00 x1bx03 x00x03
ix00
')
>>> bytearray(unicodedata.normalize('NFC', 'người'), 'utf-16')
bytearray(b'xffxfe                # BOM.
nx00                           # n.
gx00                           # g.
xb0x01                        # Latin u with horn.
xddx1e                        # Latin o with horn & grave.
ix00                           # i.
')

我不完全确定你在使用什么语言(目前没有标签(,但如果它声称可以处理Unicode,它应该有等效的功能来完成这项工作(因此,如果你稍后添加标签,我仍然认为这个答案很有用(。

只需在您选择的搜索引擎中搜索<your_language> unicode normalisation即可。

最新更新