Python 如何让str.translate使用Unicode字符串?
我有以下代码:Python 如何让str.translate使用Unicode字符串?,python,unicode,string,Python,Unicode,String,我有以下代码: import string def translate_non_alphanumerics(to_translate, translate_to='_'): not_letters_or_digits = u'!"#%\'()*+,-./:;<=>?@[\]^_`{|}~' translate_table = string.maketrans(not_letters_or_digits,
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)
导入字符串
def translate_非字母数字(to_translate,translate_to=''):
不是字母或数字=u'!"#%\'()*+,-./:;?@[\]^_`{|}~'
translate\u table=string.maketrans(不是字母或数字,
翻译成
*len(不是字母或数字)
返回到_translate.translate(translate_表)
这对于非unicode字符串非常有效:
>>> translate_non_alphanumerics('<foo>!')
'_foo__'
>>> 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
翻译非字母数字(“!”)
"乌福"
但对于unicode字符串失败:
>>> translate_non_alphanumerics('<foo>!')
'_foo__'
>>> 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
>>翻译非字母数字(u'!')
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第5行,翻译为非字母数字
TypeError:字符映射必须返回整数、无或unicode
我无法理解str.translate()方法中关于“Unicode对象”的段落
如何对Unicode字符串执行此操作?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和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)
def translate_非字母数字(to_translate,translate_to=u''):
不是字母或数字=u'!“#%\'()*+,-./:@[\]^_`{|}~'
如果isinstance(转换为unicode):
translate_table=dict((ord(字符),unicode(translate_to))
对于非字母或数字形式的字符)
其他:
断言isinstance(要翻译,str)
translate\u table=string.maketrans(不是字母或数字,
翻译成
*len(不是字母或数字)
返回到_translate.translate(translate_表)
更新:“强制”将unicode
translate\u表
转换为unicode。感谢Mike。提供了一个简单的hack,可用于str和unicode对象,
在运行translate()之前,将转换表转换为unicode:
导入字符串
def translate_非字母数字(to_translate,translate_to=''):
不是字母或数字=u'!"#%\'()*+,-./:;?@[\]^_`{|}~'
translate\u table=string.maketrans(不是字母或数字,
翻译成
*len(不是字母或数字)
翻译表格=翻译表格。解码(“拉丁语-1”)
返回到_translate.translate(translate_表)
这里需要注意的是,它将隐式地将所有str对象转换为unicode,
如果to_translate包含非ascii字符,则引发错误。您不必指定所有需要替换的字符,也可以通过另一种方式查看,而只指定有效字符,如下所示:
import re
def replace_non_alphanumerics(source, replacement_character='_'):
result = re.sub("[^_a-zA-Z0-9]", replacement_character, source)
return result
这适用于unicode和常规字符串,并保留类型(如果
替换字符
和源代码
显然是同一类型)。在此版本中,您可以相对地将一个人的字母与另一个人的字母进行转换
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)
我发现在Python2.7中,使用类型
str
,您可以编写
import string
table = string.maketrans("123", "abc")
print "135".translate(table)
table = {ord(s): d for s, d in zip("123", "abc")}
print("135".translate(table))
而对于typeunicode
你会说
table = {ord(s): unicode(d) for s, d in zip("123", "abc")}
print u"135".translate(table)
在Python3.6中,您可以编写
import string
table = string.maketrans("123", "abc")
print "135".translate(table)
table = {ord(s): d for s, d in zip("123", "abc")}
print("135".translate(table))
也许这会有帮助。与这里的其他字符相比,我有一个独特的问题。首先,我知道我的字符串中可能有unicode字符(感谢Mac上的电子邮件…),但其中一个常见字符是emdash AKA u“\u2014”字符,需要转换(返回)为两个破折号AKA”--“。可能找到的其他字符是单字符翻译,因此它们与其他解决方案类似 首先,我为emdash创建了一个dict。对于这些,我使用一个简单的string.replace()来转换它们。其他类似的字符也可以在这里处理
uTranslateDict = {
u"\u2014": "--", # Emdash
}
然后我为1:1的翻译创建了一个元组。这些代码通过string.translate()内置
然后是函数
def uTranslate(uToTranslate):
uTranslateTable = dict((ord(From), unicode(To)) for From, To in uTranslateTuple)
for c in uTranslateDict.keys():
uIntermediateStr = uToTranslate.decode("utf-8").replace(c, uTranslateDict[c])
return uIntermediateStr.translate(uTranslateTable)
因为我知道输入字符串的格式,所以我不必担心两种类型的输入字符串。我建议您强制将translate\u转换为Unicode版本的Unicode,否则如果您将Unicode字符串传递给translate调用,则translate调用将异常,并且“正常”这似乎应该成为语言的一部分+谢谢你!(这样一个愚蠢的设计决定需要有一个同名的函数,它的操作方式不同。)另外,如果您不想手动定义标点字符:import string;translate_table={ord(unicode(c))for c in string.标点符号}注意:这不会翻译所有特殊的unicode标点符号(有吨…)您的
非字母或数字
缺少“$”和“&”。我建议使用字符串。标点符号
而不是硬编码集合或字符。最好使用导入字符串;字符串.标点符号
而不是实数编码中的硬编码而不是字母或数字。我明白了,你更愿意直言不讳。