string - 错误的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
,and U+2011
(连字符和不间断连字符)可能看起来完全相同,因为后者只是前者的不间断版本。
如果您将两个字符串泵入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'\xff\xfe # Unicode BOM for UTF-16.
n\x00 # n.
g\x00 # g.
u\x00 \x1b\x03 # u, combining horn.
o\x00 \x1b\x03 \x00\x03 # o, combining horn & grave.
i\x00 # i.
')
>>> bytearray(unicodedata.normalize('NFD', 'người'), 'utf-16')
bytearray(b'\xff\xfe # Identical to previous, it
n\x00 # was already decomposed.
g\x00
u\x00 \x1b\x03
o\x00 \x1b\x03 \x00\x03
i\x00
')
>>> bytearray(unicodedata.normalize('NFC', 'người'), 'utf-16')
bytearray(b'\xff\xfe # BOM.
n\x00 # n.
g\x00 # g.
\xb0\x01 # Latin u with horn.
\xdd\x1e # Latin o with horn & grave.
i\x00 # i.
')
我不完全确定您使用的是什么语言(目前没有标签)但是,如果它声称可以处理 Unicode,它应该有等效的功能来执行此操作(因此,如果您稍后添加标签,我仍然认为这个答案很有用)。
只需<your_language> unicode normalisation
在您选择的搜索引擎中搜索即可。
推荐阅读
- react-native - TouchableWithoutFeedback 从不触发触摸事件
- c# - 如何在填字游戏中选择和取消选择
- html - 我怎样才能覆盖整个分离器容器?
- javascript - java.lang.IllegalStateException:您不能为处于错误状态的广告调用 show()(在 Splash 之后)
- php - Easy APNS、PHP、Swift 3、推送通知问题
- reactjs - ReactJS:如何在滚动页面时更新状态
- c# - ASP.NET Core MVC 中不同 HttpGet 方法之间的控制器属性不一致
- javascript - 无法在 reactjs 中为自动完成设置 zIndex
- gcc - 如何在 gdb 的反汇编代码中显示 const 变量名?
- python - gtk python网格调整大小