我在Python中有一个Unicode字符串,我想删除所有的重音(变音符)。
我在网上找到了一个优雅的方法(在Java中):
将Unicode字符串转换为它的长规范化形式(使用单独的字符表示字母和变音符) 删除所有Unicode类型为“变音符”的字符。
我需要安装一个库,如pyICU或这是可能的Python标准库?那么python3呢?
重要提示:我希望避免使用从重音字符到非重音对应字符的显式映射的代码。
我在Python中有一个Unicode字符串,我想删除所有的重音(变音符)。
我在网上找到了一个优雅的方法(在Java中):
将Unicode字符串转换为它的长规范化形式(使用单独的字符表示字母和变音符) 删除所有Unicode类型为“变音符”的字符。
我需要安装一个库,如pyICU或这是可能的Python标准库?那么python3呢?
重要提示:我希望避免使用从重音字符到非重音对应字符的显式映射的代码。
当前回答
我刚刚在网上找到了这个答案:
import unicodedata
def remove_accents(input_str):
nfkd_form = unicodedata.normalize('NFKD', input_str)
only_ascii = nfkd_form.encode('ASCII', 'ignore')
return only_ascii
它工作得很好(例如,对于法语),但我认为第二步(删除重音)可能比删除非ascii字符处理得更好,因为这对于某些语言(例如,希腊语)会失败。最好的解决方案可能是显式地删除标记为变音符的unicode字符。
编辑:这招管用:
import unicodedata
def remove_accents(input_str):
nfkd_form = unicodedata.normalize('NFKD', input_str)
return u"".join([c for c in nfkd_form if not unicodedata.combining(c)])
如果字符c可以与前面的字符组合,主要是如果它是一个变音符,则unicodedata. combined (c)将返回true。
编辑2:remove_accent需要unicode字符串,而不是字节字符串。如果你有一个字节字符串,那么你必须像这样解码成一个unicode字符串:
encoding = "utf-8" # or iso-8859-15, or cp1252, or whatever encoding you use
byte_string = b"café" # or simply "café" before python 3.
unicode_string = byte_string.decode(encoding)
其他回答
Gensim .utils.deaccent(text)来自Gensim -人类主题建模:
'Sef chomutovskych komunistu dostal postou bily prasek'
另一种解决方案是unicode。
请注意,建议的unicodedata解决方案通常只删除某些字符中的重音(例如,它将“ova”变成了“”,而不是“l”)。
我刚刚在网上找到了这个答案:
import unicodedata
def remove_accents(input_str):
nfkd_form = unicodedata.normalize('NFKD', input_str)
only_ascii = nfkd_form.encode('ASCII', 'ignore')
return only_ascii
它工作得很好(例如,对于法语),但我认为第二步(删除重音)可能比删除非ascii字符处理得更好,因为这对于某些语言(例如,希腊语)会失败。最好的解决方案可能是显式地删除标记为变音符的unicode字符。
编辑:这招管用:
import unicodedata
def remove_accents(input_str):
nfkd_form = unicodedata.normalize('NFKD', input_str)
return u"".join([c for c in nfkd_form if not unicodedata.combining(c)])
如果字符c可以与前面的字符组合,主要是如果它是一个变音符,则unicodedata. combined (c)将返回true。
编辑2:remove_accent需要unicode字符串,而不是字节字符串。如果你有一个字节字符串,那么你必须像这样解码成一个unicode字符串:
encoding = "utf-8" # or iso-8859-15, or cp1252, or whatever encoding you use
byte_string = b"café" # or simply "café" before python 3.
unicode_string = byte_string.decode(encoding)
这里已经有很多答案,但之前没有考虑过:使用sklearn
from sklearn.feature_extraction.text import strip_accents_ascii, strip_accents_unicode
accented_string = u'Málagueña®'
print(strip_accents_unicode(accented_string)) # output: Malaguena®
print(strip_accents_ascii(accented_string)) # output: Malaguena
如果您已经在使用sklearn处理文本,这一点特别有用。这些是由CountVectorizer等类内部调用的函数,用于规范化字符串:当使用strip_accent ='ascii'时,则调用strip_accents_ascii;当使用strip_accent ='unicode'时,则调用strip_accents_unicode。
更多的细节
最后,考虑文档字符串中的这些细节:
Signature: strip_accents_ascii(s)
Transform accentuated unicode symbols into ascii or nothing
Warning: this solution is only suited for languages that have a direct
transliteration to ASCII symbols.
and
Signature: strip_accents_unicode(s)
Transform accentuated unicode symbols into their simple counterpart
Warning: the python-level loop and join operations make this
implementation 20 times slower than the strip_accents_ascii basic
normalization.
实际上,我在项目兼容的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'
对于@ mini夸克的回答:
我试图读取一个csv文件,它是一半法语(包含重音),也有一些字符串,最终将成为整数和浮动。 作为测试,我创建了一个test.txt文件,如下所示:
M, Montré艾尔,关于12.89太阳è弗兰çoise,不889,ël
我必须包括第2行和第3行才能让它工作(这是我在python ticket中找到的),以及加入@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)