【问题标题】:Python - Remove accents from all files in folderPython - 从文件夹中的所有文件中删除重音符号
【发布时间】:2011-02-08 16:05:21
【问题描述】:

我正在尝试从文件夹中的所有编码文件中删除所有重音符号。我已经成功构建文件列表,问题是当我尝试使用 unicodedata 进行规范化时出现错误: ** Traceback(最近一次通话最后一次): 文件“/usr/lib/gedit-2/plugins/pythonconsole/console.py”,第 336 行,在 __run self.namespace 中的 exec 命令 文件“”,第 2 行,在 UnicodeDecodeError:“utf8”编解码器无法解码位置 25 中的字节 0xf3:无效的继续字节 **

if options.remove_nonascii:
    nERROR = 0
    print _("# Removing all acentuation from coding files in %s") % (options.folder)
    exts = ('.f90', '.f', '.cpp', '.c', '.hpp', '.h', '.py'); files=set()
    for dirpath, dirnames, filenames in os.walk(options.folder):
        for filename in (f for f in filenames if f.endswith(exts)):
            files.add(os.path.join(dirpath,filename))   
    for i in range(len(files)):
        f = files.pop() ;
        os.rename(f,f+'.BACK')
        with open(f,'w') as File:
            for line in open(f+'.BACK').readlines():
                try:
                    newLine = unicodedata.normalize('NFKD',unicode(line)).encode('ascii','ignore')
                    File.write(newLine)
                except UnicodeDecodeError:
                    nERROR +=1
                    print "ERROR n %i - Could not remove from Line: %i" % (nERROR,i)
                    newLine = line
                    File.write(newLine)

【问题讨论】:

    标签: python filesystems


    【解决方案1】:

    看起来该文件可能使用 cp1252 编解码器进行编码:

    In [18]: print('\xf3'.decode('cp1252'))
    ó
    

    unicode(line) 失败,因为unicode 试图用utf-8 编解码器解码line,因此出现错误UnicodeDecodeError: 'utf8' codec can't decode...

    您可以先尝试使用 cp1252 解码 line,如果失败,请尝试 utf-8:

    if options.remove_nonascii:
        nERROR = 0
        print _("# Removing all acentuation from coding files in %s") % (options.folder)
        exts = ('.f90', '.f', '.cpp', '.c', '.hpp', '.h', '.py'); files=set()
        for dirpath, dirnames, filenames in os.walk(options.folder):
            for filename in (f for f in filenames if f.endswith(exts)):
                files.add(os.path.join(dirpath,filename))   
        for i,f in enumerate(files):
            os.rename(f,f+'.BACK')
            with open(f,'w') as fout:
                with open(f+'.BACK','r') as fin:
                    for line fin:
                        try:
                            try:
                                line=line.decode('cp1252')
                            except UnicodeDecodeError:
                                line=line.decode('utf-8')
                                # If this still raises an UnicodeDecodeError, let the outer
                                # except block handle it
                            newLine = unicodedata.normalize('NFKD',line).encode('ascii','ignore')
                            fout.write(newLine)
                        except UnicodeDecodeError:
                            nERROR +=1
                            print "ERROR n %i - Could not remove from Line: %i" % (nERROR,i)
                            newLine = line
                            fout.write(newLine)
    

    顺便说一句,

    unicodedata.normalize('NFKD',line).encode('ascii','ignore')
    

    有点危险。例如,它会完全删除 u'ß' 和一些引号:

    In [23]: unicodedata.normalize('NFKD',u'ß').encode('ascii','ignore')
    Out[23]: ''
    
    In [24]: unicodedata.normalize('NFKD',u'‘’“”').encode('ascii','ignore')
    Out[24]: ''
    

    如果这是个问题,请使用unidecode module

    In [25]: import unidecode
    In [28]: print(unidecode.unidecode(u'‘’“”ß'))
    ''""ss
    

    【讨论】:

      【解决方案2】:

      使用 unicode(line) 时可能需要指定编码,例如 unicode(line, 'utf-8')

      如果你不知道,sys.getfilesystemencoding() 可能是你的朋友。

      【讨论】:

        猜你喜欢
        • 2016-09-01
        • 2012-04-29
        • 2018-11-10
        • 1970-01-01
        • 1970-01-01
        • 2017-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多