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+2010
和U+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
(字母的修饰符(。在第二个中,它是单个1b0
、Latin small letter U with horn
(已经内置到代码点的修饰符(。
类似地,ờ
是第一个中的6f 31b 300
,三个独立的代码点表示Latin small letter O
、combining 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
即可。