如何获得str.translate使用Unicodestring?
我有以下代码:
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)
这对于非Unicodestring非常有用:
>>> translate_non_alphanumerics('<foo>!') '_foo__'
但unicodestring失败:
>>> 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文档中的“Unicode对象”的段落,我无法理解。
我如何使这个工作的Unicodestring?
Unicode版本的translate需要从Unicode序号(您可以通过ord
检索单个字符)映射到Unicode序号。 如果要删除字符,则映射到“ None
。
我改变了你的函数来build立一个字典映射每个字符的序数到你想要翻译的序数:
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__'
编辑:事实certificate,翻译映射必须从Unicode序号(通过ord
)映射到另一个Unicode序号,Unicodestring或None(要删除)。 因此,我将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)
我想到了我的原始函数和Mike的Unicode和ASCIIstring的版本的以下组合:
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为unicode translate_table
。 谢谢Mike。
对于可以在str和unicode对象上工作的简单hack,在运行translate()之前将转换表转换为unicode:
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)) translate_table = translate_table.decode("latin-1") return to_translate.translate(translate_table)
这里的问题是,它会隐式地将所有str对象转换为unicode,如果to_translate包含非ascii字符则抛出错误。
不必指定所有需要replace的字符,也可以用相反的方法查看它,而只指定有效的字符,如下所示:
import re def replace_non_alphanumerics(source, replacement_character='_'): result = re.sub("[^_a-zA-Z0-9]", replacement_character, source) return result
这与unicode以及常规string一起工作,并保留该types(如果replacement_character
和source
显然是同一types的话)。
我发现,在Python 2.7中,typesstr
,你会写
import string table = string.maketrans("123", "abc") print "135".translate(table)
而与typesunicode
你会说
table = {ord(s): unicode(d) for s, d in zip("123", "abc")} print u"135".translate(table)
在Python 3.6中,你会写
table = {ord(s): d for s, d in zip("123", "abc")} print("135".translate(table))
也许这是有帮助的。