如何在Python 3.5中删除重音并获取带有unicodedata或其他解决方案的字符串?

时间:2015-10-25 10:30:56

标签: python unicode diacritics

我想在谷歌地理编码api中使用一个字符串。我检查了很多线程,但我仍然面临问题,我不明白如何解决它。

我需要addresse1成为没有任何特殊字符的字符串。例如,Addresse1就是:“32 rue d'AthènesParisFrance”。

addresse1= collect.replace(' ','+').replace('\n','') 
addresse1=unicodedata.normalize('NFKD', addresse1).encode('utf-8','ignore') 

这里我有一个没有任何重音的字符串...... Ho no ...它不是字符串而是字节。所以我完成了建议和'解码:

addresse1=addresse1.decode('utf-8') 

但是,然后addresse1与开始时完全一样......我该怎么办?我究竟做错了什么?或者unicode我不明白的是什么?或者有更好的解决方案吗?

谢谢,

斯特凡。

5 个答案:

答案 0 :(得分:19)

第三方套餐:unidecode

3>> unidecode.unidecode("32 rue d'Athènes Paris France")
"32 rue d'Athenes Paris France"

答案 1 :(得分:2)

  

addresse1 = unicodedata.normalize(' NFKD',addresse1).encode(' utf-8','忽略')

您可能需要.encode('ascii', 'ignore')来删除非ASCII字符。 UTF-8包含所有字符,因此对它的编码不会消除任何字符,并且使用它的编码 - 解码循环是无操作。

  

有更好的解决方案吗?

这取决于你想要做什么。

如果您只想删除变音符号而不丢失所有其他非ASCII字符,则可以在NFKD规范化后读取unicodedata.category每个字符,并删除M类中的字符。

如果您希望音译为ASCII,这将成为需要自定义替换的特定于语言的问题(例如,德语ö变为oe,而不是瑞典语。)

如果您只是想将字符串捏成ASCII,因为其中包含非ASCII字符会导致某些代码中断,那么修复该代码以使所有Unicode字符正常工作比破坏良好数据更好。字母è不能用ASCII编码,但它们都不是所有字符的99.9989%,所以几乎不能使它“特殊”。仅支持ASCII的代码是蹩脚的。

Google地理编码API可以很好地使用Unicode,因此您没有明显的理由需要执行此操作。

ETA:

url2= 'maps.googleapis.com/maps/api/geocode/json?address=' + addresse1 ...

啊,您需要对注入URL的任何数据进行URL编码。这不仅仅适用于Unicode - 以上内容也会破坏许多ASCII标点符号。使用urllib.quote对单个字符串进行编码,或使用urllib.encode转换多个参数:

params = dict(
    address=address1.encode('utf-8'),
    key=googlekey
)
url2 = '...?' + urllib.urlencode(params)

(在Python 3中urllib.parse.quoteurllib.parse.encode,他们会自动选择UTF-8,因此您不必在那里手动编码。)

data2 = urllib.request.urlopen(url2).read().decode('utf-8')
data3=json.loads(data2)

json.loads读取字节字符串,因此您可以安全地省略UTF-8解码。无论如何json.load将直接从类似文件的对象中读取,因此您根本不必将数据加载到字符串中:

data3 = json.load(urllib.request.urlopen(url2))

答案 2 :(得分:2)

通常,有两种方法:(1)正则表达式和(2)str.translate

1)正则表达式

分解字符串并替换Unicode块\u0300-\u036f中的字符:

import unicodedata
import re
word = unicodedata.normalize("NFD", word)
word = re.sub("[\u0300-\u036f]", "", word)

它可以消除口音,扬扬音符,腹泻等现象

pingüino > pinguino
εἴκοσι εἶσι > εικοσι εισι

对于某些语言,可能是另一个障碍,例如Armenian script[\u0559-\u055f]

2)str.translate

首先,创建替换表(区分大小写),然后应用它。

repl = str.maketrans(
    "áéúíó",
    "aeuio"
)
word.translate(repl)

多字符替换如下:

repl = {
    ord("æ"): "ae",
    ord("œ"): "oe",
}
word.translate(repl)

答案 3 :(得分:1)

我在生成标签时遇到了类似的问题,用户可能必须使用手机输入这些标签。

不使用第 3 方软件包,您可以简化上面 bobinces 的回答:

collect = "32 rue d'Athènes Paris France"
unicode_collect = unicodedata.normalize('NFD', collect)
address1 = unicode_collect.encode('ascii', 'ignore').decode('utf-8')

address1:
"32 rue d'Athenes Paris France"

答案 4 :(得分:0)

您可以使用python中的translate()方法。 这是从tutorialspoint.com复制的示例:

#!/usr/bin/python

from string import maketrans   # Required to call maketrans function.

intab = "aeiou"
outtab = "12345"
trantab = maketrans(intab, outtab)

str = "this is string example....wow!!!";
print str.translate(trantab)

输出:

  

th3s 3s str3ng 2x1mpl2 .... w4w !!!

因此,您可以比使用replace()

更轻松地定义要替换的字符