0

我在 mac os x 10.6 上的 python 2.7 上运行,文件在 utf8 中,终端在 utf8 中。

我想在给定字符串中存在的元音 å、ä 或 ö 的每次出现后添加一个句点。

这是我正在尝试做的简化版本:

# coding: utf8

a = 'change these letters äöå'

b = map( (lambda x: a.replace(x, "{0}.".format(x))), 'åäö')

for c in b:
    print c

产生以下输出:

change these letters ?.??.??.?
change these letters äöå.
change these letters ?.??.??.?
change these letters ä.öå
change these letters ?.??.??.?
change these letters äö.å

为什么我得到带有问号的行?经过进一步研究,这样做会产生相同的问号。

# coding: utf8

for letter in 'åäö':
    print letter

输出:

?
?
?
?
?
?

但是在之前明确添加 u 给出

# coding: utf8
for letter in u'åäö':
    print letter

输出:

å
ä
ö

显式解码和编码回字符串utf8仍然会产生问号。这里有什么问题?这个循环中发生了什么?

旁注:在愚蠢的例子中,你会看到我想要做什么。实际上,我正在使用一个保存字符串的对象,以便映射操作发生在同一个字符串上。所以这个map()调用实际上每次都用一个新的元音调用对象的方法,从而更新保存在对象中的字符串。该对象的方法使用来自第二个参数的元音执行替换map并更新存储的字符串。

4

2 回答 2

2

您正在将匿名函数映射到字符串上;你应该将它映射到一个字符串列表上。Python 解释器仍将接受您给它的指令,将字符串视为一个序列并将 lambda 应用于该序列的每个组件。但在这种情况下,组件是字符串的单个字节,每个 unicode 字符是两个字节。所以替换执行了六次。

此外,在其中的三个迭代中,替换与替换 unicode 前缀字节0xc3(在 中出现 3 次äöå)的操作相同0xc3.,这会破坏字符串中的字符编码a并产生原始字节乱码。在其他三个迭代中,您将 unicode char 的第二个字节替换为该字节后跟一个句点,因此生成的字符串仍包含相关字符的字节序列,您将获得所需的结果。但这并不是因为您将整个字符替换为该字符后跟一个句点。

相比:

>>> a = 'change these letters äöå'
>>> b = map( (lambda x: a.replace(x, "{0}.".format(x))), 'å ä ö'.split())
>>> for c in b:
...   print c
... 
change these letters äöå.
change these letters ä.öå
change these letters äö.å
于 2013-06-01T03:03:15.683 回答
1

您正在迭代字节串中的字节。由于编码为 UTF-8 的非 ASCII 字符使用多个字节,因此您正在破坏字符。如果您必须遍历字符,则遍历 a 的字符unicode

于 2013-06-01T03:31:17.800 回答