在python中替换多个char映射中的字符

时间:2015-03-25 19:27:22

标签: python encode codec

我还没有能够找到解决这个问题的方法,而且我在一些糟糕的平台代码中找不到解决办法,我无能为力。我想渲染UTF-8字符串,但如果它收到一个支持字符映射的字符,平台就会崩溃。在这里的情况下,我在俄罗斯有德国Navi单位 - 拉丁文2(iso-8859-2)和西里尔文(iso-8859-5),但平台在阿拉伯字符上崩溃。所以我想过滤掉任何不是德语或俄语的东西。

此代码:

import codecs
import string

if __name__ == '__main__':
    s = u'Ivan Krsti\u0107\u0416'

    print s

    print s.encode ('iso-8859-1', 'replace')
    print s.encode ('iso-8859-5', 'replace').decode('iso-8859-5')
    print s.encode ('iso-8859-2', 'replace').decode('iso-8859-2')

可生产

Ivan KrstićЖ 
Ivan Krsti??
Ivan Krsti?Ж
Ivan Krstić?

我的问题是如何将字符映射组合为' iso-8859-2'和' iso-8859-5'所以我在过滤后得到第一个结果? (假设我已经将UTF-8编码为unicode。)

1 个答案:

答案 0 :(得分:0)

您可以使用集合生成对任一编解码器有效的所有代码点:

iso_8859_2 = {chr(i).decode('iso-8859-2') for i in xrange(0xff)}
iso_8859_5 = {chr(i).decode('iso-8859-5') for i in xrange(0xff)}
combined = iso_8859_2 | iso_8859_5

然后将其转换为正则表达式:

import re
# escape meta characters
invalid = u''.join(combined).replace('-', r'\-').replace(']', r'\]')
invalid = re.compile(u'([^{}])'.format(invalid))

并将其应用于Unicode文本以过滤掉那些不属于这些代码点的代码点:

text_using_only_iso_8859_2_or_5 = invalid.sub('', unicodetext)

然后删除任何给定字符集中 not 的所有代码点。

您还可以使用unicode.translate(),它将代码点(整数)映射到新的代码点,或None删除字符:

all_of_unicode = set(range(0x10ffff))
iso_8859_2 = {ord(chr(i).decode('iso-8859-2')) for i in xrange(0xff)}
iso_8859_5 = {ord(chr(i).decode('iso-8859-5')) for i in xrange(0xff)}
# map the difference to None values
to_remove = dict.fromkeys(all_of_unicode - iso_8859_2 - iso_8859_5)
text_using_only_iso_8859_2_or_5 = unicodetext.translate(to_remove)