繁体   English   中英

Python字符串比较 - 特殊/ Unicode字符的问题

[英]Python String Comparison--Problems With Special/Unicode Characters

我正在编写一个Python脚本来处理一些音乐数据。 它应该通过比较它们的条目并匹配它们来合并两个独立的数据库。 它几乎正常工作,但在比较包含特殊字符(即重音字母)的字符串时失败。 我很确定它是ASCII与Uni​​code编码问题,因为我收到错误:

“Unicode相等比较无法将两个参数都转换为Unicode - 将它们解释为不相等”

我意识到我可以使用正则表达式来删除有问题的字符,但我正在处理大量数据并且依赖正则表达式使我的程序变得非常慢。 有没有办法让Python正确比较这些字符串? 这里发生了什么 - 有没有办法判断它是否将我的字符串存储为ASCII或Unicode?

编辑1:我使用的是Python v2.6.6。 检查类型后,我发现一个数据库向我发出Unicode字符串,一个给出ASCII。 所以这可能就是问题所在。 我正在尝试将ASCII字符串从第二个数据库转换为Unicode,使用类似的行

line = unicode(f.readline().decode(latin_1).encode(utf_8))

但这会产生如下错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 41: ordinal not in range(128)

我不确定'ascii'编解码器为什么抱怨,因为我正在尝试 ASCII解码。 有人可以帮忙吗?

Unicode与字节

首先,一些术语。 有两种类型的字符串,编码和解码:

  • 编码。 这是存储在磁盘上的内容。 对于Python来说,它是一堆0和1,你可能会像ASCII一样对待它,但它可能是任何东西 - 二进制数据,JPEG图像,等等。 在Python 2.x中,这称为“字符串”变量。 在Python 3.x中,它更准确地称为“字节”变量。
  • 解码。 这是一串实际字符。 它们可以编码为8位ASCII字符串,也可以编码为32位中文字符。 但是在转换为编码变量之前,它只是一个Unicode字符串。

这对你意味着什么

所以这就是事情。 你说你得到一个ASCII变量和一个Unicode变量。 这实际上不是真的。

  • 你有一个变量,它是一个字节串 - 1和0,大概是8个变量。这是你假设错误地变成ASCII的变量。
  • 您有另一个变量,即Unicode数据 - 数字,字母和符号。

在将字符串与Unicode字符串进行比较之前,您必须做出一些假设。 在你的情况下,Python(和你)假设字节串是ASCII编码的。 这很好,直到你遇到一个 ASCII字符 - 一个带有重音符号的字符。

所以你需要找出编码的字符串是什么。 它可能是latin1。 如果是,您想要这样做:

if unicode_variable == string_variable.decode('latin1')

Latin1基本上是ASCII加上一些扩展字符,如Ç和Â。

如果您的数据是Latin1,那就是您需要做的。 但是如果你的字节串是用其他东西编码的,你需要弄清楚它是什么编码并将它传递给decode()。

最重要的是,除非您知道(或做出一些假设)输入数据的编码 ,否则没有简单的答案。

我会怎么做

尝试在字符串字符串上运行var.decode('latin1')。 那会给你一个Unicode变量。 如果这样做,并且数据看起来正确(即,带有重音符号的字符看起来像它们属于),请滚动它。

哦,如果latin1不解析或看起来不正确,请尝试utf8 - 另一种常见编码。

您可能需要预处理数据库并将所有内容转换为UTF-8。 我的猜测是你在某些条目中有拉丁文1重音字符。


至于你的问题,唯一可以确定的方法是看。 让你的脚本吐出那些不比较的脚本,然后查找字符代码。 或者只是尝试string.decode('latin1').encode('utf8')并看看会发生什么。

将两者都转换为unicode应该会有所帮助:

if unicode(str1) == unicode(str2):
    print "same" 

要确定您(不是它)是否将字符串存储为str对象或unicode对象,请print type(your_string)

您可以使用print repr(your_string) )明确地向您自己(和我们)展示您的字符串中的内容。

顺便说一句,你在什么操作系统上使用的是什么版本的Python? 如果是Python 3.x,请使用ascii()而不是repr()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM