Python 2.7从utf-8文件读取和写入“éèàçê”

时间:2013-06-12 08:20:35

标签: python python-2.7 encoding utf-8 character-encoding

我创建了这个脚本,它删除了每个尾随的空格字符,并用正确的字符替换所有坏的法语字符。

删除尾随空格字符有效,但不能替换有关替换法语字符的部分。

要读/写的文件以UTF-8编码,所以我在脚本上面添加了utf-8声明,但最后每个坏字符(如\ u00e9)都被litte square替换。

知道为什么吗?

脚本:

# --*-- encoding: utf-8 --*--

import fileinput
import sys

CRLF = "\r\n"

ACCENT_AIGU = "\\u00e9"
ACCENT_GRAVE = "\\u00e8"
C_CEDILLE = "\\u00e7"
A_ACCENTUE = "\\u00e0"
E_CIRCONFLEXE = "\\u00ea"

CURRENT_ENCODING = "utf-8"
#Getting filepath
print "Veuillez entrer le chemin du fichier (utiliser des \\ ou /, c'est pareil) :"
path = str(raw_input())
path.replace("\\", "/")

#removing trailing whitespace characters
for line in fileinput.FileInput(path, inplace=1):
    if line != CRLF:
        line = line.rstrip()
        print line
        print >>sys.stderr, line
    else:
        print CRLF
        print >>sys.stderr, CRLF
fileinput.close()

#Replacing bad wharacters
for line in fileinput.FileInput(path, inplace=1):
        line = line.decode(CURRENT_ENCODING)
        line = line.replace(ACCENT_AIGU, "é")
        line = line.replace(ACCENT_GRAVE, "è")
        line = line.replace(A_ACCENTUE, "à")
        line = line.replace(E_CIRCONFLEXE, "ê")
        line = line.replace(C_CEDILLE, "ç")
        line.encode(CURRENT_ENCODING)
        sys.stdout.write(line) #avoid CRLF added by print
        print >>sys.stderr, line
fileinput.close()

修改

输入文件包含以下类型的文本:

 * Cette m\u00e9thode permet d'appeller le service du module de tourn\u00e9e
 * <code>rechercherTechnicien</code> et retourne la liste repr\u00e9sentant le num\u00e9ro 
 * de la tourn\u00e9e ainsi que le nom et le pr\u00e9nom du technicien et la dur\u00e9e 
 * th\u00e9orique por se rendre au point d'intervention.
 * 

EDIT2

最终代码如果有人感兴趣,第一部分替换编码错误的字符,第二部分删除所有正确的尾随空格字符。

# --*-- encoding: iso-8859-1 --*--

import fileinput
import re

CRLF = "\r\n"

print "Veuillez entrer le chemin du fichier (utiliser des \\ ou /, c'est pareil) :"
path = str(raw_input())
path = path.replace("\\", "/")

def unicodize(seg):
    if re.match(r'\\u[0-9a-f]{4}', seg):
        return seg.decode('unicode-escape')
    return seg.decode('utf-8')

print "Replacing caracter badly encoded"
with open(path,"r") as f:
    content = f.read()
replaced = (unicodize(seg) for seg in re.split(r'(\\u[0-9a-f]{4})',content))

with open(path, "w") as o:
    o.write(''.join(replaced).encode("utf-8"))

print "Removing trailing whitespaces caracters"
for line in fileinput.FileInput(path, inplace=1):
    if line != CRLF:
        line = line.rstrip()
        print line
    else:
        print CRLF
fileinput.close()

print "Done!"

3 个答案:

答案 0 :(得分:4)

您正在寻找s.decode('unicode_escape')

>>> s = r"""
...  * Cette m\u00e9thode permet d'appeller le service du module de tourn\u00e9e
...  * <code>rechercherTechnicien</code> et retourne la liste repr\u00e9sentant le num\u00e9ro
...  * de la tourn\u00e9e ainsi que le nom et le pr\u00e9nom du technicien et la dur\u00e9e
...  * th\u00e9orique por se rendre au point d'intervention.
...  *
... """
>>> print(s.decode('unicode_escape'))

 * Cette méthode permet d'appeller le service du module de tournée
 * <code>rechercherTechnicien</code> et retourne la liste représentant le numéro
 * de la tournée ainsi que le nom et le prénom du technicien et la durée
 * théorique por se rendre au point d'intervention.
 *

在将字符串写入文件(例如UTF-8)之前,不要忘记encode字符串:

writable_s = s.decode('unicode_escape').encode('utf-8')

答案 1 :(得分:4)

不是那么快,而且很脏,但是......

with open("enc.txt","r") as f:
    content = f.read()

import re

def unicodize(seg):
    if re.match(r'\\u[0-9a-f]{4}', seg):
        return seg.decode('unicode-escape')

    return seg.decode('utf-8')

replaced = (unicodize(seg) for seg in re.split(r'(\\u[0-9a-f]{4})',content))

print(''.join(replaced))

鉴于输入文件(混合unicode转义序列和正确编码的utf-8文本):

 * Cette m\u00e9thode permet d'appeller le service du module de
 * tourn\u00e9e
 * <code>rechercherTechnicien</code> et retourne la liste
 * repr\u00e9sentant le num\u00e9ro 
 * de la tourn\u00e9e ainsi que le nom et le pr\u00e9nom du technicien
 * et la dur\u00e9e 
 * th\u00e9orique por se rendre au point d'intervention.
 * 
 * S'il le désire le technicien peut dormir à l'hôtel

产生结果:

 * Cette méthode permet d'appeller le service du module de
 * tournée
 * <code>rechercherTechnicien</code> et retourne la liste
 * représentant le numéro 
 * de la tournée ainsi que le nom et le prénom du technicien
 * et la durée 
 * théorique por se rendre au point d'intervention.
 * 
 * S'il le désire le technicien peut dormir à l'hôtel

答案 2 :(得分:1)

读取以utf-8编码的文件,其中包含非ascii字符,字面上包含\u00,{{ 1}},e您还要解码的字符序列:

9

注意:通常,非ascii字符和Unicode转义符(import codecs import re repl = lambda m: m.group().encode('ascii', 'strict').decode('unicode-escape') with codecs.open(filename, encoding='utf-8') as file: text = re.sub(r'\\u[0-9a-f]{4}', repl, file.read()) )不应混合在一个文件中。使用一个或另一个但不能同时使用。

  

要读/写的文件以UTF-8编码,所以我在脚本上面添加了utf-8声明

Python源代码中的utf-8声明仅影响Python源代码的字符编码,例如,它允许在bytestring和unicode文字中使用非ascii字符。 对您阅读的文件的字符编码没有影响

  

但最后每个坏字符(如\ u00e9)都被litte square替换。

“litte square”可能是打印到控制台的工件。在控制台中尝试此操作以查看是否存在方块:

\uxxxx