如何使str.translate与Unicode字符串一起工作?

2024-05-23 15:05:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下代码:

import string
def translate_non_alphanumerics(to_translate, translate_to='_'):
    not_letters_or_digits = u'!"#%\'()*+,-./:;<=>?@[\]^_`{|}~'
    translate_table = string.maketrans(not_letters_or_digits,
                                       translate_to
                                         *len(not_letters_or_digits))
    return to_translate.translate(translate_table)

对于非unicode字符串非常有用:

>>> translate_non_alphanumerics('<foo>!')
'_foo__'

但unicode字符串失败:

>>> translate_non_alphanumerics(u'<foo>!')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in translate_non_alphanumerics
TypeError: character mapping must return integer, None or unicode

对于str.translate()方法,Python 2.6.2 docs中关于“Unicode对象”的段落我没有任何意义。

如何使它适用于Unicode字符串?


Tags: orto字符串stringreturnfootableunicode
3条回答

我想出了以下我的原始函数和Mike版本的组合,它可以使用Unicode和ASCII字符串:

def translate_non_alphanumerics(to_translate, translate_to=u'_'):
    not_letters_or_digits = u'!"#%\'()*+,-./:;<=>?@[\]^_`{|}~'
    if isinstance(to_translate, unicode):
        translate_table = dict((ord(char), unicode(translate_to))
                               for char in not_letters_or_digits)
    else:
        assert isinstance(to_translate, str)
        translate_table = string.maketrans(not_letters_or_digits,
                                           translate_to
                                              *len(not_letters_or_digits))
    return to_translate.translate(translate_table)

更新:“强制”translate_to为unicode的unicodetranslate_table。谢谢迈克。

Unicode版本的translate需要从Unicode序数(可以用^{}检索单个字符)到Unicode序数的映射。如果要删除字符,则映射到None

我更改了您的函数以构建一个dict,将每个字符的序号映射到要转换为的序号:

def translate_non_alphanumerics(to_translate, translate_to=u'_'):
    not_letters_or_digits = u'!"#%\'()*+,-./:;<=>?@[\]^_`{|}~'
    translate_table = dict((ord(char), translate_to) for char in not_letters_or_digits)
    return to_translate.translate(translate_table)

>>> translate_non_alphanumerics(u'<foo>!')
u'_foo__'

编辑:结果是转换映射必须从Unicode序号(通过ord)映射到另一个Unicode序号、Unicode字符串或无(要删除)。因此,我将translate_to的默认值更改为Unicode文本。例如:

>>> translate_non_alphanumerics(u'<foo>!', u'bad')
u'badfoobadbad'

在这个版本中,你可以相对地把一个人的信写给另一个人

def trans(to_translate):
    tabin = u'привет'
    tabout = u'тевирп'
    tabin = [ord(char) for char in tabin]
    translate_table = dict(zip(tabin, tabout))
    return to_translate.translate(translate_table)

相关问题 更多 >