Python 带unicode字符修饰符

Python 带unicode字符修饰符,python,unicode,utf-8,Python,Unicode,Utf 8,在Python中,从unicode字符串中去除字符修饰符的最简单方法是什么 例如: 应该成为亚瑟王 我尝试了文档,但找不到任何可以这样做的东西。试试这个 import unicodedata a = u"STRING GOES HERE" # using an actual string would break stackoverflow's code formatting. u"".join( x for x in a if not unicodedata.category(x).starts

在Python中,从unicode字符串中去除字符修饰符的最简单方法是什么

例如:

应该成为亚瑟王

我尝试了文档,但找不到任何可以这样做的东西。

试试这个

import unicodedata
a = u"STRING GOES HERE" # using an actual string would break stackoverflow's code formatting.
u"".join( x for x in a if not unicodedata.category(x).startswith("M") )

这将删除所有分类为标记的字符,这是我认为您想要的。通常,您可以使用Unicode Data.category获取字符的类别。

您还可以使用以下支持的
r'\p{M}

例如:

>>> print s
A͋͠r͍̞̫̜t̼̭͞h́u̡̙̞̘rͬͣ̐ͮ
>>> def remove_marks(text):
...     return regex.sub(ur"\p{M}+", "", text)
...     
... 
>>> print remove_marks(s)
Arthur
根据您的使用情况,白名单方法可能更好,例如,将输入仅限于ascii字符:

>>> s.encode('ascii', 'ignore').decode('ascii')
u'Arthur'

结果可能取决于文本中使用的Unicode规范化。

+1。但是最好在这里使用
.startswith('M')
而不是
'M'。从6.1开始,任何类别都没有“M”子类别,但没有规则说将来不会有。@abarnert:那么你是说最好使用将来可能会坏掉的东西?@martineau:不,最好使用将来不会坏掉的东西。如果添加了
M
类别的子类别,则该子类别将用于组合标记。如果添加了其他类别的新
M
子类别,则该子类别将不用于组合标记。因此,组合标记的正确规则是
cat.startswith('M')
,而不是cat中的
'M'。(这不太可能出现,因为他们没有添加任何新的子类别来共享主类别使用的字母,并清空了唯一现有的子类别,
LC
。但是做正确的事情没有坏处,至少有潜在的好处。)在进一步研究之后,我不确定这两种方式是否真的重要。据我所知,unicode字符数据库有类别和子类别,由单个字符以“Xx”的形式表示。因此,在
中使用
'M'将在将来起作用,因为子类别将是'M',StartWith也将继续起作用。Startswith更有意义,因为它总是第一个角色;除非类别名称发生了根本性的变化,否则情况就是这样。在这种情况下,你很难期望相同的代码起作用。标准化的一个或多个标记可能会组成一个字母,在这种情况下,你会丢失该字母。但您可以通过执行unicoredata.normalize('NFD',s.)、encode('ascii','ignore')、decode('ascii')
来解决这个问题。(您可能希望改用“NFKD”,这取决于您是否希望获得U+2160(
I
)之类的东西,如果是这样,您是希望将它们视为兼容的等效U+0049(
I
)还是跳过它们。)
>>> s.encode('ascii', 'ignore').decode('ascii')
u'Arthur'