我在做一个过滤器,检查一个Unicode(UTF-8编码)字符串是否不包含大写字符(在所有语言中)。如果字符串根本不包含任何大小写字符,我也可以。

例如:"你好!"不会通过过滤器,但"!"应该通过过滤器,因为"!"不是大小写字符。

我计划使用islower()方法,但在上面的示例中,"!".islower()将返回false。

根据python文档,"如果unicode字符串的大小写字符都是小写并且字符串至少包含一个大小写字符,则python unicode方法islower()返回true,否则返回false。"

因为当字符串不包含任何大小写字符时,该方法也返回false,即"!",我想检查字符串是否包含任何大小写字符。

像这样的……

string = unicode("!@#$%^", 'utf-8')
#check first if it contains cased characters
if not contains_cased(string):
return True
return string.islower():

有没有关于contains_cased()函数的建议?

或者可能是另一种实现方法?

谢谢!

您接受的答案似乎不正确。看看我的答案。

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

阿格·亚历克斯,有什么你不知道的吗?

-1将东亚字符视为"cased"。看看我的答案。

+1:工作方案(与没有john machine可执行代码的漂亮解释相比)

以下是关于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计算)。其中很大一部分是朝鲜文音节、CJK汉字和其他东亚字符——很难理解它们是如何被视为"大小写"的。

您可能需要考虑一个基于您所期望的"cased characters"的(未指定)行为的替代定义。下面是一个简单的第一次尝试:

>>> 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 lu,总共2153…进一步调查ll和lu的真正含义的范围。

约翰:哇。谢谢你的解释。我花了一段时间才明白。我看了你的链接,我想我必须更广泛地研究它。我有一种感觉,我将要发现的是,将使我大修我的代码很多。伊克斯。谢谢!

@阿尔伯特:别惊慌。正如我所暗示的,首先要对你所说的"cased"进行定义。与未装箱字符相比,您将对装箱字符采用什么不同的处理方法?我的示例定义是"char,其大小写为'partner'"。1970年chars和2153之间的一些(可能全部)差异似乎是由于chars被分类为Ll,因为它们看起来像小写字符,但没有Lu伙伴,反之亦然——您需要决定这些字符是否为您的目的"加了壳"。顺便说一句,您可以更改已接受的答案:—)

@约翰:嗯,我正在为我的Web服务开发一个API。我的WebService接受一个映射到我数据库中特定记录的键。该键区分大小写,可以由任何Unicode字符组成。因此,为了规范化所有输入,我将把所有键查询转换为小写(如果它们具有大写等价物)。这样做的结果是,当我创建记录键(我的用户可以自定义)时,我不能接受任何大写字符,这些字符可以通过tolower()函数转换为小写等效字符。所以我要做一个过滤器。有什么建议吗?

@阿尔伯特:如果你的钥匙是区分大小写的,你为什么要使它们正常化???""记录用户可以自定义的密钥"是什么意思???"任何Unicode字符"vs"都不能接受任何大写字符????从字面上回答你的问题:当c.lower() != c时,你不能接受字符c,这意味着如果key.lower() != key时你不能接受任何键。我认为你应该开始一个新的问题,用例子准确地解释你想做什么。BTW1:别忘了先接受这个问题的答案。btw2:python没有toLower函数…

@约翰:我的错。我指的是lower()函数。好吧,我来开始一个新问题。谢谢!

@约翰:我尊重你的Unicode专长。我有一个新问题,你认为你能看一下吗?如果答案是正确的,你也能看一下。谢谢!stackoverflow.com/questions/3536397/…

您把小写字母误认为是小写代码点。这些是小写代码点,但不是小写字母:u+0345 GC=MnCOMBINING GREEK YPOGEGRAMMENI、u+2176 GC=NlSMALL ROMAN NUMERAL SEVEN、u+24da GC=SoCIRCLED LATIN SMALL LETTER K。这些是大写时不改变大小写的小写字母:U+00aa GC=LlFEMININE ORDINAL INDICATOR、U+0262 GC=LlLATIN LETTER SMALL CAPITAL G、U+02b0 GC=LmMODIFIER LETTER SMALL H、U+2093 GC=LmLATIN SUBSCRIPT SMALL LETTER X、U+210a GC=LlSCRIPT SMALL G和U+1D521 EDOCX1〔11〔11〕LATIN LETTER SMALL CAPITAL G和U+1D521 EDOCX1〔11〔11〔11〕EDOCX1〔11〔14〕和U+1d521 EDOCX11〔11〔11〔11〕MODIFIER LETTER SMALL H和U+2093 GC=LmGC=Lmedcx1〔18〕]MATHEMATICAL FRAKTUR SMALL D。

使用模块unicodedata,

unicodedata.category(character)

对于小写字母返回"EDOCX1"〔1〕,对于大写字母返回"EDOCX1"〔2〕。

您可以在这里找到Unicode字符类别的列表