【问题标题】:How do I match all unicode lowercase characters in Python with a regular expression?如何将 Python 中的所有 unicode 小写字符与正则表达式匹配?
【发布时间】:2021-09-26 09:41:54
【问题描述】:

我正在尝试编写一个匹配 Python 3 中的 Unicode 小写字符的正则表达式。我正在使用 re 库。例如,re.findall(some_pattern, 'u∏ñKθ') 应该返回 ['u', 'ñ', 'θ']

在 Sublime Text 中,我可以简单地输入 [[:lower:]] 来查找这些字符。

我知道 Python 可以匹配任何带有 re.compile('[^\W\d_]') 的 Unicode 字符,但我特别需要区分大写和小写。我也知道re.compile('[a-z]') 可以匹配任何 ASCII 小写字符,但我的数据是 UTF-8,它包含许多非 ASCII 字符——我检查过。

这是否可以在 Python 3 中使用正则表达式,或者我需要采取其他方法吗?我知道其他方法可以做到这一点。我只是希望使用正则表达式。

【问题讨论】:

标签: python python-3.x regex unicode re


【解决方案1】:

您不需要使用 PyPi regex 库(尽管我强烈建议在这里使用它,因为它支持 POSIX 字符类(如 [:lower:])和 Unicode 属性类如 \p{Ll}):

import re, sys
lower = '[{}]'.format("".join([chr(i) for i in range(sys.maxunicode) if chr(i).islower()]))
print(re.findall(lower, 'ABCabcÆæóżźę'))
# => ['a', 'b', 'c', 'æ', 'ó', 'ż', 'ź', 'ę']

Python proof

结果

['a', 'b', 'c', 'æ', 'ó', 'ż', 'ź', 'ę']

【讨论】:

    【解决方案2】:

    您可以使用支持 POSIX 字符类的regex module

    import regex 
    
    >>> regex.findall('[[:lower:]]', 'u∏ñKθ')
    ['u', 'ñ', 'θ']
    

    或者,使用\p{Ll}\p{Lowercase_Letter}Unicode Category Class

    >>> regex.findall(r'\p{Ll}', 'u∏ñKθ')
    ['u', 'ñ', 'θ']
    

    或者直接使用 Python 的字符串逻辑:

    >>> [c for c in 'u∏ñKθ' if c.islower()]
    ['u', 'ñ', 'θ']
    

    在任何一种情况下,都要小心这样的字符串:

    >>> s2='\u0061\u0300\u00E0'
    >>> s2
    'àà'
    

    第一个grapheme 'à''a''̀' 组合字符的结果,其中第二个'à' 是该特定代码点的结果。如果您在此处使用字符类,它将匹配 'a' 而不是组合重音:

    >>> regex.findall('[[:lower:]]', s2)
    ['a', 'à']
    >>> [c for c in s2 if c.islower()]
    ['a', 'à']
    

    要解决这个问题,您需要使用更复杂的正则表达式模式或normalize the string

    >>> regex.findall('[[:lower:]]', unicodedata.normalize('NFC',s2))
    ['à', 'à']
    

    或按字形循环字形:

    >>> [c for c in regex.findall(r'\X', s2) if c.islower()]
    ['à', 'à']
    

    【讨论】:

    • 感谢您的提示。我试图避免使用.islower(),因为我没有透露的部分问题是我正在寻找几种特定的字符类型组合,例如,一个大写字符后跟至少一个小写字符也允许一些特殊字符。这就是为什么我特别想要一个正则表达式。我将安装和使用正则表达式模块。谢谢!
    【解决方案3】:

    如果可以使用第三方包,您可以使用regex 包。

    >>> import regex
    >>> s = 'ABCabcÆæ'
    >>> m = regex.findall(r'[[:lower:]]', s)
    >>> m
    ['a', 'b', 'c', 'æ']
    

    【讨论】:

    • 我通常对第三方软件包持谨慎态度,但如果我可以通过conda 访问它,我可以通过这个特定的软件包访问它,那么冒险是值得的。看起来这将是我最好的选择。谢谢!
    【解决方案4】:

    试试这个 -

    import re
    
    a = re.findall('[^\W\d_]', 'u∏ñKθ')
    
    for i in a:
        if i.islower():
            print(i)
    

    re.findall 找到所有的 UTF-8 字符,然后用.islower() 过滤掉,检查它们是否是小写字符,然后打印出来

    【讨论】:

    • 没有意义使用 for 循环,当简单的列表理解更合适时。我不赞成你的回答,因为你不赞成我的回答。
    • 当你想建立一个列表时使用列表推导。在这里,我打印的是值而不是列表
    • 谢谢!我简化了我的问题以使其更清楚。完整的问题以及我想使用正则表达式的原因是我正在寻找字符类型的特定组合。例如,一个大写字符后跟 1 个或多个小写字符或特定的特殊字符。当我对 Python 的 re 库感到沮丧时,我最初在 lambda 函数中写下了所有这些规则,但它们很丑陋,所以我又通过了第二遍。不过,感谢您的意见!
    猜你喜欢
    • 2015-05-01
    • 1970-01-01
    • 2022-01-19
    • 2014-12-15
    • 2021-10-16
    • 2016-07-13
    • 1970-01-01
    • 2013-10-18
    • 1970-01-01
    相关资源
    最近更新 更多