在Python中将Unicode映射到ASCII



我通过urlopen以JSON格式查询后收到字符串:

def get_clean_text(text):
    return text.translate(maketrans("!?,.;():", "        ")).lower().strip()
for track in json["tracks"]:
    print track["name"].lower()
    get_clean_text(track["name"].lower())

对于字符串"türlich,tüllich(sicher,dicker)",我得到

文件"main.py",第23行,在get_clean_text 中

return text.translate(maketrans("!?,.;():", "        ")).lower().strip()

TypeError:字符映射必须返回integer、None或unicode

我想将字符串格式化为"türlich tüllich sicher dicker"。

这个问题不是一个完全独立的例子;我不确定是Python 2还是3,maketrans来自哪里,等等。我很有可能猜错了,这就是为什么你应该确保适当地标记你的问题,并提供一个简短、独立、正确的例子。(这一点,以及其他各种人——其中一些人可能比我更聪明——可能因为你的问题模棱两可而忽略了你的问题。)

假设您使用2.x,并且您已经执行了from string import *以获得maketrans,并且json["name"]是unicode而不是str/bytes,那么您的问题如下:

有两种类型的转换表:老式的8位表(只是256个字符的数组)和新型的稀疏表(只是将一个字符的序数映射到另一个字符上的dict)。str.translate函数可以使用其中一个,但unicode.translate只能使用第二个(如果你仔细考虑一下,原因应该很明显)。

string.maketrans函数生成旧式的8位转换表。所以您不能将它与unicode.translate一起使用。

您可以随时编写自己的"makeunitrans"函数作为替换,类似于以下内容:

def makeunitrans(frm, to):
  return {ord(f):ord(t) for (f,t) in zip(frm, to)}

但如果你只想绘制出某些字符,你可以做一些更特殊的事情:

def makeunitrans(frm):
  return {ord(f):ord(' ') for f in frm}

然而,从你最后的评论来看,我不确定translate是否是你想要的:

我想将字符串格式化为"türlich tüllich sicher dicker"

如果你做对了,你将把字符串格式化为"türlich tüllich sicher dicker",因为你将所有这些标点符号映射到空格,而不是什么都映射。

使用新型的转换表,您可以将任何想要的内容映射到None,从而解决了这个问题。但是,您可能想退一步问,为什么一开始就使用translate方法,而不是多次调用replace(人们通常说"为了性能",但如果这是一个问题,您不会每次都在内联中构建翻译表)或使用一个琐碎的正则表达式。

最新更新