识别字符串中是否存在Ñ。
cadena = "DADEVVEÑWE"
如果我做:
for letra in cadena:
if letra == 'D':
print 'Letra D'
elif letra == 'Ñ':
print 'Letra Ñ'
为什么你跳过Ñ并且看不到它们?如果你看到它们,其余的字母(如果我把它们对应的条件)。我在哪里应用编码以便它识别Ñ?
识别字符串中是否存在Ñ。
cadena = "DADEVVEÑWE"
如果我做:
for letra in cadena:
if letra == 'D':
print 'Letra D'
elif letra == 'Ñ':
print 'Letra Ñ'
为什么你跳过Ñ并且看不到它们?如果你看到它们,其余的字母(如果我把它们对应的条件)。我在哪里应用编码以便它识别Ñ?
这是由于 Python 2 使用非 ascii 字符的方式。
事实证明,当您在源代码中放入这样的一行时:
实际进入变量的内容取决于您使用的编辑器。
如果您使用使用 ISO 编码的编辑器(例如,许多 windows 编辑器),则三个字节将存储在变量中,因为在该编码中,每个字母都是一个字节(并且字母的代码
Ñ
将是f1
)。如果您使用使用 UTF-8 编码的编辑器(目前最标准,在 Linux 和 Mac 甚至 Windows 上,具体取决于您使用的编辑器),那么变量中将包含四个字节,因为在该编码中,一些字母只占用一个字节(ascii)和两个或三个其他字节。特别是 eñe 将使用两个字节的 value
c3
和进行编码91
。这会带来各种问题,例如
len(cadena)
它可能会根据您使用的编辑器返回 4 或 3。因此,从您的程序将不得不处理可能包含非 ascii 字符的文本的那一刻起,必须做的就是始终使用 Unicode。
在 python 2 中,Unicode 是另一种类型的变量,不同于
str
. 要将字符串放在 Unicode 中,您必须u
在引号前面加上一个。所以:在这种情况下,Python 统一编码字符串中的每个字符。它们都需要 32 位(尽管这对我们来说真的是透明的)。unicode 字符串上的函数
len()
告诉您它有多少个字母,而不是多少字节,因此无论您在哪个编辑器中键入它,它都会返回 3。如果您有一个不是程序源代码的一部分但已从外部(从文件、从套接字或通过
raw_input()
)读取的字符串,它将是一个字符串str
,即一个字节序列。为了能够在您的程序中处理它并将其与其他 Unicode 进行比较,您还必须将它们转换为 Unicode。例如像这样:如您所见,这种转换的问题在于,您必须指定字符串所在的编码
str
。在此示例中"utf8"
,假设我从中读取文本的终端使用 utf8。如果您使用其他编码,则转换可能会失败。如果您从文件中读取,则相同,您必须知道文件的编码是什么。去你的例子。您有与此等效的代码:
正如你所看到的,
cadena
它是类型的str
(因为它不领先u
于前面)。如果您从使用 UTF8 的编辑器编写此代码,则该字符串将包含四个字节,如上所述。这意味着循环将重复四次(如您所见,如果您运行它)。在每次迭代中,letra
它将是一个字节。在它的任何一次迭代中,都不是真的letra == "Ñ"
,因为它们"Ñ"
是两个字节,如前所述。现在他神秘的离开是有道理的:
它会像这样固定:
我们仍然混合了普通字符串和 unicode 字符串,这很容易搞砸。Python3 通过默认将所有字符串设为 Unicode 来简化这一点。
除了@abulafia 的回答,它很好地解释了为什么会发生这种情况以及如何避免它,我想补充一点,为了不出现这种类型的错误,可以在文件开头的注释中指定编码. 例如 utf8,这是 python 3 中的默认值:
utf-8
如果需要,可以用另一种编码代替,例如latin-1
或utf-64