【问题标题】:RegEx: Find all digits after certain string正则表达式:查找特定字符串后的所有数字
【发布时间】:2016-02-10 08:43:29
【问题描述】:

我正在尝试从单词classes或其变体)之后的以下字符串中获取所有数字

Accepted for all the goods and services in classes 16 and 41.

预期输出:

16
41

我有多个遵循这种模式的字符串以及其他一些字符串,例如:

classes 5 et 30 # expected output 5, 30
class(es) 32,33 # expected output 32, 33
class 16        # expected output 5

这是我迄今为止尝试过的:https://regex101.com/r/eU7dF6/3

(class[\(es\)]*)([and|et|,|\s]*(\d{1,}))+

但在上面的例子中,我只能得到最后一个匹配的数字,即41

【问题讨论】:

    标签: python regex


    【解决方案1】:

    我建议在classclasses/class(es) 之后获取所有带有数字的子字符串,然后从中获取所有数字:

    import re
    p = re.compile(r'\bclass(?:\(?es\)?)?(?:\s*(?:and|et|[,\s])?\s*\d+)+')
    test_str = "Accepted for all the goods and services in classes 16 and 41."
    results = [re.findall(r"\d+", x) for x in p.findall(test_str)]
    print([x for l in results for x in l])
    # => ['16', '41']
    

    IDEONE demo

    由于不支持\G 构造,您也无法使用Python re 模块访问捕获堆栈,因此您无法使用您的方法。

    但是,您可以像 PyPi regex module 那样做。

    >>> import regex
    >>> test_str = "Accepted for all the goods and services in classes 16 and 41."
    >>> rx = r'\bclass(?:\(?es\)?)?(?:\s*(?:and|et|[,\s])?\s*(?P<num>\d+))+'
    >>> res = []
    >>> for x in regex.finditer(rx, test_str):
            res.extend(x.captures("num"))
    >>> print res
    ['16', '41']
    

    【讨论】:

    • 感谢 Wiktor,但是您所建议的也是一种双重方法,就像vks 提供的答案一样,我当然可以使用这种方法。但我想有一个可以给我结果的正则表达式。
    • 但是你可以使用 PyPi 正则表达式模块吗?我说过你不能在re 中使用单个正则表达式。
    • 使用外部库根本不是问题。 :)
    • @AKS 如果不是问题,您可以检查我的编辑...不要在 python 中使用regex 模块
    • 感谢 Wiktor,我使用了带有正确正则表达式的正则表达式模块,效果很好!
    【解决方案2】:

    您可以分两步完成。Regex 引擎只记住连续组中的最后一组。

    x="""Accepted for all the goods and services in classes 16 and 41."""
    print re.findall(r"\d+",re.findall(r"class[\(es\)]*\s*(\d+(?:(?:and|et|,|\s)*\d+)*)",x)[0])
    

    输出:['16', '41']

    如果你不想string使用

    print map(ast.literal_eval,re.findall(r"\d+",re.findall(r"class[\(es\)]*\s*(\d+(?:(?:and|et|,|\s)*\d+)*)",x)[0]))
    

    输出:[16, 41]

    如果您必须在一个正则表达式中执行此操作,请使用 regex 模块

    import regex
    x="""Accepted for all the goods and services in classes 16 and 41."""
    print [ast.literal_eval(i) for i in regex.findall(r"class[\(es\)]*|\G(?:and|et|,|\s)*(\d+)",x,regex.VERSION1) if i]
    

    输出:[16, 41]

    【讨论】:

    • 是的!事实上,我可以做到这一点。但我只是想知道是否有一个纯正则表达式可以满足我的需求。
    • @AKS 检查编辑..您可以使用regex 模块进行操作,但默认 python 中不存在
    • @vks: :) 那里是睡觉时间吗?见this demo,你就会明白了。
    猜你喜欢
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    相关资源
    最近更新 更多