【问题标题】:Regular Expression to match multiple postive lookahead groups正则表达式匹配多个正向前瞻组
【发布时间】:2016-12-08 12:43:50
【问题描述】:

这是我目前的正则表达式:

^(?=.*(option1|option2))(?=.*(option3|option4))(?=.*(option5|option6))(?=.*(option7|option8))(?=.*(option9|option10)).*$

我不熟悉正则表达式语言,所以我会自己定义:

第1类是(option1|option2),第2类是(option3|option4),第3类是(option5|option6),等等。

我想捕获从 3 个或更多类别中找到至少 1 个选项的值,如下所示:

一些文本 option3 一些文本 option8 一些文本 option1

一些文本 option3 一些文本 option8 一些文本 option1 一些文本 option6

我不想捕获这样的值:

一些文本 option3 一些文本 option8 - 仅代表 2 个类别

一些文本 option3 一些文本 option4 一些文本 option1(选项 3 和 4 属于同一类别)

选项可以在文本中以任意顺序出现,这就是我使用正向预读的原因,但我不知道如何在多个正向预读上放置量词。

就正则表达式引擎而言,我必须在后台使用由 python 提供支持的前端 UI。我只能使用正则表达式,我没有能力使用任何其他 python 函数。谢谢!

【问题讨论】:

    标签: python regex regex-lookarounds


    【解决方案1】:

    这是一个可以满足您需求的正则表达式(VERBOSE 模式):

    ^
    (?= .* (?: option1 | option2 )  () )?
    (?= .* (?: option3 | option4 )  () )?
    (?= .* (?: option5 | option6 )  () )?
    (?= .* (?: option7 | option8 )  () )?
    (?= .* (?: option9 | option10 ) () )?
    .*$
    (?: \1\2\3 | \1\2\4 | \1\2\5 | \1\3\4 | \1\3\5 |
        \1\4\5 | \2\3\4 | \2\3\5 | \2\4\5 | \3\4\5 )
    

    空组用作复选框:如果封闭的前瞻不成功,则对该组的反向引用将不会成功。最后的非捕获组包含五个反向引用中的三个的所有可能组合。

    这种方法的局限性是显而易见的;你只需要再添加一组options 就可以让它完全失控。我认为您最好使用非正则表达式解决方案。

    【讨论】:

    • 感谢您提供此解决方案!你能再解释一下VERBOSE模式是什么吗?我必须使用的前端 UI 不允许更改为 VERBOSE 模式。这可以用python的默认模式写吗(不知道叫什么)?
    • 您可以在正则表达式本身中指定 VERBOSE 模式,方法是在开头添加 (?x)。或者您可以从正则表达式中删除所有空格:^(?=.*(?:option1|option2)())?(?=.*(?:option3|option4)())?(?=.*(?:option5|option6)())?(?=.*(?:option7|option8)())?(?=.*(?:option9|option10)())?.*$(?:\1\2\3|\1\2\4|\1\2\5|\1\3\4|\1\3\5|\1\4\5|\2\3\4|\2\3\5|\2\4\5|\3\4\5)
    【解决方案2】:

    我认为这不能通过正则表达式实现,或者如果可以(可能在某些步骤中),这不是一个正确的方法。

    相反,您可以将选项存储在如下集合中:

    options = {(option1, option2), (option3, option4), (option5, option6), (option7, option8), (option9, option10)}
    

    然后检查成员资格如下:

    if sum(i in my_text or j in my_text for i, j in options) >= 3:
        # do something
    

    这是一个演示:

    >>> s1 = "some text option8 some more text option3 some more text option1"
    >>> s2 = "some text option3 some more text option4 some more text option1"
    >>> s3 = "some text option3 some more text option8"
    >>> 
    >>> options = {('option1', 'option2'), ('option3', 'option4'), ('option5', 'option6'), ('option7', 'option8'), ('option9', 'option10')}
    >>> 
    >>> sum(i in s1 or j in s1 for i, j in options)
    3
    >>> sum(i in s2 or j in s2 for i, j in options)
    2
    >>> sum(i in s3 or j in s3 for i, j in options)
    2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      • 2020-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多