2010-08-18 55 views
8

我正在做一个过滤器,其中我检查一个unicode(utf-8编码)字符串是否不包含大写字符(所有语言)。如果字符串根本不包含任何套装字符,那就没有问题。Python:如何检查一个unicode字符串是否包含一个套用字符?

例如:'你好!'不会通过过滤器,但“!”应该通过过滤器,因为“!”不是一个容器的角色。我打算使用islower()方法,但在上面的示例中,“!”。islower()将返回False。

根据Python Docs的说法,“如果unicode字符串的封装字符全部为小写,并且该字符串至少包含一个封装字符,则python unicode方法islower()返回True,否则返回False。

由于该方法在字符串不包含任何套用字符时也返回False,即。 “!”,我想检查字符串是否包含任何套装字符。

事情是这样的....

string = unicode("[email protected]#$%^", 'utf-8') 

#check first if it contains cased characters 
if not contains_cased(string): 
    return True 

return string.islower(): 

的contains_cased()函数有什么建议?

或者可能是一种不同的实现方法?

谢谢!

+0

您接受的答案似乎不正确。看到我的答案。 – 2010-08-18 22:09:38

回答

6

Here是Unicode字符类别的勺子。

信类别包括:

Ll -- lowercase 
Lu -- uppercase 
Lt -- titlecase 
Lm -- modifier 
Lo -- other 

注意Ll <-> islower();同样为Lu; (Lu or Lt) <-> istitle()

您可能希望阅读有关套管的复杂讨论,其中包括对Lm字母的一些讨论。

盲目地把所有的“字母”视为封套是明显错误的。Lo类别包括BMP中的45301个码点(使用Python 2.6计算)。其中很大一部分是Hangul Syllables,CJK Ideographs和其他东亚人物 - 很难理解它们如何被认为是“套用”的。

您可能希望根据您期望的“套用字符”的(未指定)行为来考虑其他定义。这里有一个简单的第一次尝试:

>>> cased = lambda c: c.upper() != c or c.lower() != c 
>>> sum(cased(unichr(i)) for i in xrange(65536)) 
1970 
>>> 

有趣的是,有1216 x ll和937 x路,总共2153 ...进一步调查Ll和Lu真正意义的范围。

+0

@John:哇。谢谢你的解释。我花了一段时间才明白它。我看了一下你的链接,我想我必须更广泛地研究它。我有一种感觉,即将发现将会让我彻底改变我的许多代码。让人惊讶。 谢谢! – Albert 2010-08-19 05:40:46

+0

@Albert:不要惊慌。正如我所暗示的那样,首先要制定一个你所说的“套用”的定义。你会采用什么不同的待遇来装箱,而不是无字符的字符?我的示例定义是“具有大写或小写”伙伴“的字符”。 1970年代的字符和2153年之间的一些差异(可能全部)似乎是归因于被分类为“Ll”的字符,因为它们看起来像小写字符,但没有“Lu”字符,反之亦然 - 你需要决定这些是否是“为了你的目的”。顺便说一句,你可以改变你接受的答案:-) – 2010-08-19 06:07:46

+0

@John:嗯,我实际上是为我的web服务制作一个API。我的web服务接受一个映射到我的数据库中的特定记录的密钥。密钥区分大小写,密钥可以由任何unicode字符组成。所以为了规范化所有的输入,我会将所有的关键查询转换成小写(如果它们有大写的等价物)。这样做的结果是当我创建记录键(我的用户可以自定义)时,我无法接受任何可以通过toLower()函数转换为小写字母的大写字符。所以我试图为此做一个过滤器。有什么建议么? – Albert 2010-08-20 12:54:35

7
import unicodedata as ud 

def contains_cased(u): 
    return any(ud.category(c)[0] == 'L' for c in u) 
+0

阿格亚历克斯,有什么你不知道的? – 2010-08-18 07:19:03

+2

-1将东亚字符视为“包含”。看到我的答案。 – 2010-08-18 08:10:12

+0

+1:工作解决方案(与没有John Machin可执行代码的很好的解释相比) – oDDsKooL 2012-07-03 08:45:53

1

使用模块unicodedata

unicodedata.category(character) 

返回 “Ll” 为小写字母和 “Lu” 大写的人。

here你可以找到的Unicode字符类别列表