关于utf 8:从python中的Windows-1252(cp1252)文件正确读取文本

Correctly reading text from Windows-1252(cp1252) file in python

好吧,正如标题所示,我的问题是从python中的Windows-1252编码文件中正确读取输入并将所述输入插入SQLAlchemy-MySql表中。

当前系统设置:
Windows 7 VM,带有" Roger访问控制系统",用于输出文件;
具有Windows系统共享文件夹的Ubuntu 12.04 LTS VM,因此我可以使用" Python 2.7.3"访问该文件。

由于实际问题,对于输入文件,我有一个" VM共享文件夹",其中包含一个文件,该文件通过Roger Access Control系统在Windows 7系统上生成(有关更多详细信息,请参见roger.pl)。称为" PREvents.csv",其内容提示为";"单独的数据列表。

数据的示例格式:

1
2
2013-03-19;15:58:30;100;nis;Dumburs;1;Uznemums1;0;Ieeja;
2013-03-19;15:58:40;100;nis;Dumburs;1;Uznemums1;2;Izeja;

第4个字段包含卡所有者的姓名,第5个字段包含所有者的姓氏,第6个字段包含所有者分配的组。

问题来自上述三个字段中的任何一个都可以包含特定于拉脱维亚语言的字符,在示例文件中,单词" Janis"包含字母"ā",Unicode中的字母为257。

按照我的习惯,我这样打开文件:

1
2
3
4
try:
    f = codecs.open(file, 'rb', 'cp1252')
except IOError:
    f = codecs.open(file, 'wb', 'cp1252')

到目前为止,一切正常,它打开了文件,因此我继续遍历文件的每一行(这是一个连续运行的脚本,请原谅循环):

1
2
3
4
5
6
7
8
9
while True:
    line = f.readline()

    if not line:
        # Pause loop for 1 second
        time.sleep(1)
    else:
        # Split the line into list
        date, timed, userid, firstname, lastname, groupid, groupname, typed, pointname, empty = line.split(';')

这就是问题的开始,如果我print repr(firstname),它会打印u'J\\xe2nis',据我所知,这是不正确的-'\\\\ xe2 \\\\不代表拉脱维亚字符"ā"。
根据事件类型进一步深入循环,我将变量分配给SQLAlchemy对象并插入/更新:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
if typed == '0':  # Entry type
    event = Events(
        period,
        fullname,
        userid,
        groupname,
        timestamp,
        0,
        0
    )
    session.add(event)
else:  # Exit type
    event = session.query(Events).filter(
        Events.period == period,
        Events.exit == 0,
        Events.userid == userid
    ).first()
    if event is not None:
        event.exit = timestamp
        event.spent = timestamp - event.entry

# Commit changes to database
session.commit()

在寻找答案的过程中,我发现了如何定义要使用的默认编码:

1
2
3
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

没有任何帮助。

基本上,所有这些导致我无法插入正确的所有者的名字/姓氏以及所有者分配的组名(如果它们包含拉脱维亚的任何特定字符),例如:

1
Instead of the character"ā" it inserts"a"

我还要补充一点,我无法更改" PREvents.csv"文件的编码,并且" RACS"系统不支持插入UTF-8或Unicode文件-如果您尝试使用任何一种方法,系统都会随机插入拉脱维亚语专用字符的符号。

如果需要任何其他信息,请现在让我,我会很乐意提供它:)

我们将不胜感激。


CP1252不能代表ā;您输入的内容包含相似的字符a。 repr只是在Python 2.x中显示Unicode字符串的ASCII表示形式:

1
2
3
4
>>> print(repr(b'J\\xe2nis'.decode('cp1252')))
u'J\\xe2nis'
>>> print(b'J\\xe2nis'.decode('cp1252'))
Janis


我认为u'J\\xe2nis'是正确的,请参见:

1
2
>>> print u'J\\xe2nis'.encode('utf-8')
Janis

您是从SQLAlchemy还是在应用程序的输出中获取实际错误?


我对某些XML文件有相同的问题,我解决了使用ANSI编码(Windows-1252)读取文件并使用UTF-8编码写入文件的问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
import os
import sys

path = os.path.dirname(__file__)

file_name = 'my_input_file.xml'

if __name__ =="__main__":
    with open(os.path.join(path, './' + file_name), 'r', encoding='cp1252') as f1:
        lines = f1.read()
        f2 = open(os.path.join(path, './' + 'my_output_file.xml'), 'w', encoding='utf-8')
        f2.write(lines)
        f2.close()