在python中正确读取Windows-1252(cp1252)文件中的文本

在python中正确读取Windows-1252(cp1252)文件中的文本,python,utf-8,python-unicode,windows-1252,cp1252,Python,Utf 8,Python Unicode,Windows 1252,Cp1252,好的,正如标题所示,我的问题是正确地从python中的windows-1252编码文件中读取输入,并将所述输入插入SQLAlchemy MySql表 当前系统设置: Windows 7虚拟机,带有“罗杰访问控制系统”,输出文件 Ubuntu12.04 LTS虚拟机,带有Windows系统的共享文件夹,因此我可以使用“Python2.7.3”访问该文件 现在来看实际问题,对于输入文件,我有一个“VM共享文件夹”,其中包含一个在Windows 7系统上通过Roger访问控制系统生成的文件(更多详细信

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

当前系统设置:
Windows 7虚拟机,带有“罗杰访问控制系统”,输出文件
Ubuntu12.04 LTS虚拟机,带有Windows系统的共享文件夹,因此我可以使用“Python2.7.3”访问该文件

现在来看实际问题,对于输入文件,我有一个“VM共享文件夹”,其中包含一个在Windows 7系统上通过Roger访问控制系统生成的文件(更多详细信息,请参见Roger.pl),该文件称为“PREvents.csv”,它向其内容建议一个“;”单独的数据列表

数据格式示例如下:

2013-03-19;15:58:30;100;Jānis;Dumburs;1;Uznemums1;0;Ieeja;
2013-03-19;15:58:40;100;Jānis;Dumburs;1;Uznemums1;2;Izeja;
第四个字段包含卡所有者姓名,第五个字段包含所有者姓氏,第六个字段包含所有者分配的组

问题的根源在于上述3个字段中的任何一个都可能包含拉脱维亚语言特有的字符,在示例文件中,“Jānis”一词包含字母“ā”,在unicode中为257

我习惯于这样打开文件:

try:
    f = codecs.open(file, 'rb', 'cp1252')
except IOError:
    f = codecs.open(file, 'wb', 'cp1252')
到目前为止,一切正常-它打开了文件,因此我继续迭代文件的每一行(这是一个连续运行的脚本,请原谅循环):

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

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()
在搜索答案时,我找到了如何定义要使用的默认编码:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
这对我没有任何帮助

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

Instead of the character "ā" it inserts "â"
我还想补充一点,我无法更改“PREvents.csv”文件编码,“RACS”系统不支持插入UTF-8或Unicode文件-如果您尝试任何一种方式,系统都会为拉脱维亚特定字符插入随机符号

如果需要任何其他信息,请立即告知我,我很乐意提供:)


任何帮助都将不胜感激。

CP1252不能代表Ɂ;您的输入包含类似的字符–0
repr
仅显示Python 2.x中unicode字符串的ASCII表示形式:

>>> print(repr(b'J\xe2nis'.decode('cp1252')))
u'J\xe2nis'
>>> print(b'J\xe2nis'.decode('cp1252'))
Jânis

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

>>> print u'J\xe2nis'.encode('utf-8')
Jânis

您是否从SQLAlchemy或应用程序的输出中得到了实际错误?

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

导入操作系统
导入系统
path=os.path.dirname(_文件__)
file\u name='my\u input\u file.xml'
如果名称=“\uuuuu main\uuuuuuuu”:
将open(os.path.join(路径“./”+文件名)、“r”,编码为class='cp1252')作为f1:
lines=f1.read()
f2=打开(os.path.join(路径“./”+“my_output_file.xml”),“w”,encoding='utf-8')
f2.写入(行)
f2.关闭()

CP1252中根本没有拉脱维亚字符ā。无法创建包含该字符的CP1252编码文件。(您是否有CP1257编码的文件?);CP1252类似于(但不完全相同)ISO-8859-1,它只支持西欧语言;CP1257支持波罗的海语言。如果我尝试
firstname=firstname.decode('cp1252')
,然后将其插入数据库,我仍然会得到字符“–OK”,因此将文件打开行更改为
f=codecs.open(file,'rb',CP1257')
,然后
打印firstname
显示正确的“ā”但是现在当执行
session.commit()
时,我得到了
UnicodeEncodeError:“latin-1”编解码器无法对位置1中的字符u'\u0101'进行编码:序号不在范围(256)
您可能需要将utf-8设置为数据库(会话)的默认编码?是的,我现在已经解决了这个问题-在
engine=create\u engine(connection,convert\u unicode=True)
中创建“引擎”时需要添加
convert\u unicode=True
>>> print u'J\xe2nis'.encode('utf-8')
Jânis