在 python 中替换多个字符映射中的字符
In python replacing characters from multiple char maps
我一直未能找到解决此问题的方法,它是针对一些我无能为力的不良平台代码的解决方法。我想呈现 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。)
您可以使用集合生成对任一编解码器有效的所有代码点:
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)
这将删除任何给定字符集中不是的代码点。
您还可以使用 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)
我一直未能找到解决此问题的方法,它是针对一些我无能为力的不良平台代码的解决方法。我想呈现 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。)
您可以使用集合生成对任一编解码器有效的所有代码点:
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)
这将删除任何给定字符集中不是的代码点。
您还可以使用 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)