我在Python中有一个Unicode字符串,我想删除所有的重音符号(变音符号)。
我在网上发现了一种用Java实现此目的的优雅方法:
- 将Unicode字符串转换为长规范化格式(带有单独的字母和变音符号)
- 删除所有Unicode类型为“变音符号”的字符。
我是否需要安装pyICU之类的库,还是仅使用python标准库就可以? 那python 3呢?
重要说明:我想避免使用带有重音符号到非重音符号的显式映射的代码。
#1楼
这不仅处理重音,而且还处理“笔画”(如ø等):
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
这是我能想到的最优雅的方式(alexis在此页的评论中已经提到),尽管我认为这确实不是很优雅。 实际上,正如注释中所指出的那样,这更像是一种黑客,因为Unicode名称是–实际上只是名称,因此它们不保证其一致性或任何形式。
由于它们的Unicode名称不包含“ WITH”,因此仍然有一些特殊的字母无法对此进行处理,例如转弯和倒转字母。 无论如何,这取决于您想做什么。 有时我需要重音符号来实现字典的排序顺序。
编辑说明:
合并了注释中的建议(处理查找错误,Python-3代码)。
#2楼
回应@MiniQuark的回答:
我正在尝试读取一个半法语的csv文件(包含重音符号)以及一些最终会变成整数和浮点数的字符串。 作为测试,我创建了一个test.txt
文件,如下所示:
蒙特利尔,于伯,12.89,梅尔,弗朗索瓦,诺尔,889
我必须包括第2
行和第3
行才能使其正常工作(我在python票证中找到),并包含@Jabba的注释:
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
import csv
import unicodedata
def remove_accents(input_str):
nkfd_form = unicodedata.normalize('NFKD', unicode(input_str))
return u"".join([c for c in nkfd_form if not unicodedata.combining(c)])
with open('test.txt') as f:
read = csv.reader(f)
for row in read:
for element in row:
print remove_accents(element)
结果:
Montreal
uber
12.89
Mere
Francoise
noel
889
(注意:我在Mac OS X 10.8.4上并使用Python 2.7.3)
#3楼
Unidecode是正确的答案。 它将所有unicode字符串音译为ASCII文本中最接近的可能表示形式。
例:
accented_string = u'Málaga'
# accented_string is of type 'unicode'
import unidecode
unaccented_string = unidecode.unidecode(accented_string)
# unaccented_string contains 'Malaga'and is of type 'str'
#4楼
实际上,我正在开发与项目兼容的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'
#5楼
一些语言结合了变音符号作为语言字母和重音符号来指定重音。
我认为更明确地指定要去除的折光度数更安全:
def strip_accents(string, accents=('COMBINING ACUTE ACCENT', 'COMBINING GRAVE ACCENT', 'COMBINING TILDE')):
accents = set(map(unicodedata.lookup, accents))
chars = [c for c in unicodedata.normalize('NFD', string) if c not in accents]
return unicodedata.normalize('NFC', ''.join(chars))
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3161241