Python:如何检查Unicode字符串是否包含大小写字符?

8

我正在进行一个筛选,其中我检查一个Unicode(UTF-8编码)字符串是否不包含大写字母(在所有语言中)。如果该字符串根本不包含任何大小写字符,则对我来说也是可以的。

例如:'Hello!'不会通过筛选,但“!”应该通过筛选,因为“!”不是大小写字符。

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

根据Python文档,“python unicode方法islower()返回True,如果unicode字符串的大小写字符都是小写的,并且该字符串包含至少一个大小写字符,否则返回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() 函数的建议?

或者可能有不同的实现方法?

谢谢!


您所接受的答案似乎是不正确的。请查看我的答案。 - John Machin
3个回答

8
import unicodedata as ud

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

阿格,亚历克斯,有什么你不知道的吗? - Bite code
+1:工作解决方案(相比于John Machin的漂亮但没有可执行代码的解释) - oDDsKooL

8

这里是有关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 = lambda c: c.upper() != c or c.lower() != c
>>> sum(cased(unichr(i)) for i in xrange(65536))
1970
>>>

有趣的是,有1216个Ll和937个Lu,总共2153个...还有进一步探究Ll和Lu真正含义的空间。

@John:哇。谢谢你的解释。我花了一段时间才理解它。我看了你的链接,我觉得我需要更深入地学习它。我有一种感觉,我即将发现的东西会让我大量修改我的代码。天啊。谢谢! - Albert
@Albert:不要惊慌。正如我所暗示的,首先要制定一个“大小写”的定义。你会对大小写字符采取什么不同的处理方式?我的例子定义是“具有大写或小写‘伴侣’的字符”。一些(也许全部)1970个字符和2153个字符之间的差异似乎是由于被分类为Ll的字符,因为它们看起来像小写字符,但没有Lu伴侣,反之亦然——你需要决定这些字符是否符合你的“大小写”目的。顺便说一句,你可以更改你接受的答案 :-) - John Machin
@John:嗯,我正在为我的Web服务制作API。我的Web服务接受一个键,该键映射到我的数据库中的特定记录。该键区分大小写,并且可以由任何Unicode字符组成。因此,为了规范所有输入,我将把所有键查询转换为小写(如果它们具有大写字母等效项)。这样做的一个后果是,当我创建记录键(我的用户可以自定义)时,我不能接受任何可以通过toLower()函数转换为小写等效项的大写字符。所以我正在尝试制作一个过滤器。有什么建议吗? - Albert
@John:我的错误,我是指lower()函数。好的,我会发一个新问题。谢谢! - Albert
你将小写字母错认为小写代码点。以下是小写代码点而非小写字母:U+0345 GC=Mn 希腊语小文字母下加重音、U+2176 GC=Nl 罗马数字七、U+24DA GC=So 带圈的拉丁小写字母K。而这些小写字母不会在转换为大写时改变:U+00AA GC=Ll 阴性序数指示符、U+0262 GC=Ll 拉丁字母小型大写G、U+02B0 GC=Lm 修饰字母小型H、U+2093 GC=Lm 拉丁小型下标字母X、U+210A GC=Ll 手写体小写字母G,以及U+1D521 GC=Ll 数学分式小写字母D - tchrist
显示剩余2条评论

1

使用模块unicodedata

unicodedata.category(character)

对于小写字母返回 "Ll",对于大写字母返回 "Lu"。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接