用于 unicode 大写单词的 Python 正则表达式

Posted

技术标签:

【中文标题】用于 unicode 大写单词的 Python 正则表达式【英文标题】:Python regex for unicode capitalized words 【发布时间】:2016-07-11 06:51:28 【问题描述】:

我有一组不同语言(英语、波兰语、芬兰语、俄语等)的单词,需要检查它们中的哪些单词是用大写字母写的。

我尝试使用简单的正则表达式:^[A-Z],但它只匹配拉丁字母,然后我添加了俄语大写字母:^[A-ZА-Я]

但仍有许多 带有变音符号的 unicode 字母。如何在我的正则表达式中添加所有大写字母?

是否可以在不枚举符号的情况下做到这一点?

附:我知道,如何在 Ruby 中制作它,但现在我使用的是 Python。

【问题讨论】:

如果安装PyPi regex module,则可以使用\pLu类。 谢谢,+1,但是...我不想在我的项目中添加新的外部依赖项。 Here is a regex 所有大写字母范围。 哇 =) 谢谢!这是我见过的最大的正则表达式! 【参考方案1】:

如果您需要使用正则表达式,您有两种选择:

安装 PyPi regex module 并使用 \pLu[[:upper:]](其中包含更多大写字符)类 (make sure you have the latest version installed) 将 re 与包含所有大写字母范围的字符类一起使用,或者使用 Python 实用程序(然后匹配的 Unicode 字母的数量将取决于 Python 版本,最新的具有最新数据)或通过从Unicode Utilities CLDR page 手动创建/更新范围。

这是一个正则表达式的解决方案,其中包含取自Unicode Utilities CLDR reference page 的所有大写字母范围:

import re
pLu = "[A-Z\u00C0-\u00D6\u00D8-\u00DE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2160-\u216F\u2183\u24B6-\u24CF\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AE\uA7B0-\uA7B4\uA7B6\uFF21-\uFF3A\U00010400-\U00010427\U000104B0-\U000104D3\U00010C80-\U00010CB2\U000118A0-\U000118BF\U0001D400-\U0001D419\U0001D434-\U0001D44D\U0001D468-\U0001D481\U0001D49C\U0001D49E\U0001D49F\U0001D4A2\U0001D4A5\U0001D4A6\U0001D4A9-\U0001D4AC\U0001D4AE-\U0001D4B5\U0001D4D0-\U0001D4E9\U0001D504\U0001D505\U0001D507-\U0001D50A\U0001D50D-\U0001D514\U0001D516-\U0001D51C\U0001D538\U0001D539\U0001D53B-\U0001D53E\U0001D540-\U0001D544\U0001D546\U0001D54A-\U0001D550\U0001D56C-\U0001D585\U0001D5A0-\U0001D5B9\U0001D5D4-\U0001D5ED\U0001D608-\U0001D621\U0001D63C-\U0001D655\U0001D670-\U0001D689\U0001D6A8-\U0001D6C0\U0001D6E2-\U0001D6FA\U0001D71C-\U0001D734\U0001D756-\U0001D76E\U0001D790-\U0001D7A8\U0001D7CA\U0001E900-\U0001E921\U0001F130-\U0001F149\U0001F150-\U0001F169\U0001F170-\U0001F189]"
p = re.compile(pLu)
if p.match("Żółw"):
    print("Capitalized!")

请参阅IDEONE demo。要使其在 Python 2.x 中工作,请确保在字符串文字中添加 u 前缀。

还有其他方法可以在 Python 中使用 unicodedatasys 之类的包来获取 Unicode 大写字母 字符类

# Python 3
pLu = '[]'.format("".join([chr(i) for i in range(sys.maxunicode) if chr(i).isupper()]))
# Python 2
pLu = u'[]'.format(u"".join([unichr(i) for i in xrange(sys.maxunicode) if unichr(i).isupper()]))

但是,此范围与 Unicode Utilities: UnicodeSet 页面上显示的 [:upper:] POSIX 字符类的所有大写字母都不匹配。

参考:

Python 2.7 len([unichr(i) for i in xrange(sys.maxunicode) if unichr(i).isupper()]) 显示 1427 Python 3.5 len([chr(i) for i in range(sys.maxunicode) if chr(i).isupper()]) 显示 1751 Python 3.6 len([chr(i) for i in range(sys.maxunicode) if chr(i).isupper()]) 显示 1822 当前的 Unicode Utilities CLDR 页面显示 1,822 大写字母代表 [:upper:] 类,1,702 代表 \pLu

有了PyPi regex模块,就更简单了:

import regex
p = regex.compile(r"\pLu") # To support (currently) 1702 uppercase letters
# p = regex.compile(r"[[:upper:]]") # To support (currently) 1822 uppercase letters
if p.match("Żółw"):
    print("Capitalized!")

在 Python 2.x 中你应该使用:

p = regex.compile(ur"\pLu")
p = regex.compile(ur"[[:upper:]]")

p = regex.compile(r"\pLu", regex.U)
p = regex.compile(r"[[:upper:]]", regex.U)

【讨论】:

在 python2 中,你应该使用u"\pLu" 或使用regex.UNICODE 标志进行编译。我编辑了答案。 在 Python 2.x 中,仅 ure.U 可能还不够,但肯定是必需的。【参考方案2】:

re 是多余的,你可以使用word[0].isupper()

>>>> 'żółć'[0].isupper()
False
>>>> 'Żółw'[0].isupper()
True
>>>> 'ćMa'[0].isupper()
False

【讨论】:

@Oz123:它在您使用 Unicode 字符串时有效。要在 Python2 中使用此功能,您需要为字符串添加前缀 u,例如 u"Żółw",或者使用 from __future__ import unicode_literals 太棒了!很高兴知道!我认为顺便说一句,您应该将此作为编辑添加到您的其他答案中。【参考方案3】:
>>> words
'Does not match Äh Oh Äi Üs üx Öjjj'

>>> re.findall(r"(\b[A-ZÜÖÄ][a-z.-]+\b)", words, re.UNICODE)
['Does', 'Äh', 'Oh', 'Äi', 'Üs', 'Öjjj']

只需将所有不在 A-Z 范围内的 Unicode 字母添加到列表中,我只添加了德语变音符号。

你可以像这样找到所有非 ASCII 字母(A-Z):

>>> [c for c in words if not c.isalpha() and not c.isdigit() and not c.isspace()]
['\xc3', '\x84', '\xc3', '\x84', '\xc3', '\x9c', '\xc3', '\xbc', '\xc3', '\x96']

现在你必须弄清楚哪些是大写字母。

【讨论】:

"不用枚举符号也能做到这一点?"我的数据集中有很多语言。把所有的unicaode大写字母都加起来是相当困难的。 既然不想添加依赖,no.【参考方案4】:

您可以将字符串与其大写版本进行比较,以判断它是否大写:

>>>> s = 'żółć Żółw ćMa'
>>>> l = s.split()
>>>> [word for word in l if word == word.capitalize()]
['Żółw']
>>>> frozenset(l).intersection(s.capitalize() for s in l)
frozenset('Żółw')

请注意,在 Python2 中,您需要使用 unicode 字符串才能使其正常工作。

【讨论】:

谢谢,也 +1。但我试图只使用正则表达式来做到这一点。 这太棒了!【参考方案5】:

你应该试试\W\w

Example in pythex.org

【讨论】:

这个正则表达式工作不正确。例如,它匹配非大写单词“живете”,不匹配大写单词“Oh”。 \W - 匹配任何不是单词字符的字符。

以上是关于用于 unicode 大写单词的 Python 正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

在python中计算变量中的大写单词

如何在 Unicode 中将字符串设置为大写/小写?

python-语言元素

python学习日记1-基础

python 在字符串中转换每个单词大写。

javascript [All Caps]用于将句子中每个单词的第一个字母大写的脚本#vanilla #script