我在Python中有一个Unicode字符串,我想删除所有的重音(变音符)。
我在网上找到了一个优雅的方法(在Java中):
将Unicode字符串转换为它的长规范化形式(使用单独的字符表示字母和变音符) 删除所有Unicode类型为“变音符”的字符。
我需要安装一个库,如pyICU或这是可能的Python标准库?那么python3呢?
重要提示:我希望避免使用从重音字符到非重音对应字符的显式映射的代码。
我在Python中有一个Unicode字符串,我想删除所有的重音(变音符)。
我在网上找到了一个优雅的方法(在Java中):
将Unicode字符串转换为它的长规范化形式(使用单独的字符表示字母和变音符) 删除所有Unicode类型为“变音符”的字符。
我需要安装一个库,如pyICU或这是可能的Python标准库?那么python3呢?
重要提示:我希望避免使用从重音字符到非重音对应字符的显式映射的代码。
当前回答
这不仅可以处理重音,还可以处理“笔画”(如ø等):
import unicodedata as ud
def rmdiacritics(char):
'''
Return the base character of char, by "removing" any
diacritics like accents or curls and strokes and the like.
'''
desc = ud.name(char)
cutoff = desc.find(' WITH ')
if cutoff != -1:
desc = desc[:cutoff]
try:
char = ud.lookup(desc)
except KeyError:
pass # removing "WITH ..." produced an invalid name
return char
这是我能想到的最优雅的方式(亚历克西斯在本页的评论中提到过),尽管我不认为它真的很优雅。 事实上,正如评论中指出的那样,这更像是一种黑客,因为Unicode名称实际上只是名称,它们不能保证一致或任何东西。
仍然有一些特殊的字母没有被处理,比如反转字母和倒装字母,因为它们的unicode名称不包含'WITH'。这取决于你想做什么。我有时需要重音剥离来实现字典排序顺序。
编辑注:
合并了来自注释的建议(处理查找错误,Python-3代码)。
其他回答
在我看来,所提出的解决办法不应该是公认的答案。原来的问题是要求去掉重音,所以正确的答案应该只去掉重音,而不是去掉重音加上其他未指明的变化。
简单地观察这段代码的结果,这是公认的答案。我把“Málaga”改成了“Málagueña”:
accented_string = u'Málagueña'
# accented_string is of type 'unicode'
import unidecode
unaccented_string = unidecode.unidecode(accented_string)
# unaccented_string contains 'Malaguena'and is of type 'str'
有一个额外的更改(ñ -> n),这在OQ中没有请求。
一个简单的函数,以较低的形式完成所请求的任务:
def f_remove_accents(old):
"""
Removes common accent characters, lower form.
Uses: regex.
"""
new = old.lower()
new = re.sub(r'[àáâãäå]', 'a', new)
new = re.sub(r'[èéêë]', 'e', new)
new = re.sub(r'[ìíîï]', 'i', new)
new = re.sub(r'[òóôõö]', 'o', new)
new = re.sub(r'[ùúûü]', 'u', new)
return new
实际上,我在项目兼容的python 2.6, 2.7和3.4上工作,我必须从免费用户条目中创建id。
感谢你,我创造了这个功能,工作的奇迹。
import re
import unicodedata
def strip_accents(text):
"""
Strip accents from input String.
:param text: The input string.
:type text: String.
:returns: The processed String.
:rtype: String.
"""
try:
text = unicode(text, 'utf-8')
except (TypeError, NameError): # unicode is a default on python 3
pass
text = unicodedata.normalize('NFD', text)
text = text.encode('ascii', 'ignore')
text = text.decode("utf-8")
return str(text)
def text_to_id(text):
"""
Convert input text to id.
:param text: The input string.
:type text: String.
:returns: The processed String.
:rtype: String.
"""
text = strip_accents(text.lower())
text = re.sub('[ ]+', '_', text)
text = re.sub('[^0-9a-zA-Z_-]', '', text)
return text
结果:
text_to_id("Montréal, über, 12.89, Mère, Françoise, noël, 889")
>>> 'montreal_uber_1289_mere_francoise_noel_889'
这个怎么样:
import unicodedata
def strip_accents(s):
return ''.join(c for c in unicodedata.normalize('NFD', s)
if unicodedata.category(c) != 'Mn')
这也适用于希腊字母:
>>> strip_accents(u"A \u00c0 \u0394 \u038E")
u'A A \u0394 \u03a5'
>>>
字符类别“Mn”代表Nonspacing_Mark,它类似于MiniQuark回答中的unicodedata. combined(我没有想到unicodedata. combined,但它可能是更好的解决方案,因为它更显式)。
请记住,这些操作可能会极大地改变文本的含义。重音、变音等都不是“装饰”。
这不仅可以处理重音,还可以处理“笔画”(如ø等):
import unicodedata as ud
def rmdiacritics(char):
'''
Return the base character of char, by "removing" any
diacritics like accents or curls and strokes and the like.
'''
desc = ud.name(char)
cutoff = desc.find(' WITH ')
if cutoff != -1:
desc = desc[:cutoff]
try:
char = ud.lookup(desc)
except KeyError:
pass # removing "WITH ..." produced an invalid name
return char
这是我能想到的最优雅的方式(亚历克西斯在本页的评论中提到过),尽管我不认为它真的很优雅。 事实上,正如评论中指出的那样,这更像是一种黑客,因为Unicode名称实际上只是名称,它们不能保证一致或任何东西。
仍然有一些特殊的字母没有被处理,比如反转字母和倒装字母,因为它们的unicode名称不包含'WITH'。这取决于你想做什么。我有时需要重音剥离来实现字典排序顺序。
编辑注:
合并了来自注释的建议(处理查找错误,Python-3代码)。
Gensim .utils.deaccent(text)来自Gensim -人类主题建模:
'Sef chomutovskych komunistu dostal postou bily prasek'
另一种解决方案是unicode。
请注意,建议的unicodedata解决方案通常只删除某些字符中的重音(例如,它将“ova”变成了“”,而不是“l”)。