【问题标题】:Regular Expression: match within a match正则表达式:匹配中的匹配
【发布时间】:2017-12-20 09:57:47
【问题描述】:

我正在尝试使用正则表达式来查找包含特定单词的两个单词之间的所有内容,但是这些单词是重复的,所以我没有得到我想要的匹配。

例如,我想要“hello”和“bye”之间的所有内容,以便它们之间存在“apple”这个词:

hello sometext hello sometext apple sometext bye sometext bye

我想要的结果是“sometext apple sometext”,即满足条件的最小文本量。

但是,如果我使用 hello((?s).*apple(?s).*)bye,我会得到:

sometext hello sometext apple sometext bye sometext

【问题讨论】:

    标签: python regex python-2.7


    【解决方案1】:

    要消耗apple之前最后一个之前的所有hellos, 把.*放在图案前面:

    r'.*hello (.*?apple.*?) bye'
    

    另外,我不确定您所说的 (?s) 是什么意思。 无论如何,上面的模式都会给出你想要的结果, 例如当用作re.match(r'.*hello (.*?apple.*?) bye', s).group(1)时。

    最后, 正如@Rawing 在评论中指出的那样:

    [...] 这个正则表达式会给你 last 的出现。例如,如果输入字符串是hello apple1 bye hello apple2 bye,您将得到apple2。因此,如果您需要查找多个匹配项,则此正则表达式将不起作用。

    ...正如@bobble-bubble 回应的那样,您可以通过使用如下的前瞻来找到第一个匹配项:

    r'hello((?:(?!hello).)*?apple.*?)bye'
    

    【讨论】:

    • 此模式与re.match 一样有效。 re.search 效率较低,没有任何好处。 (假设是单行输入字符串,或全点修饰符。)
    • 我想指出的另一件事是这个正则表达式会给你 last 的出现。例如,如果输入字符串是hello apple1 bye hello apple2 bye,您将得到apple2。因此,如果您需要查找不止一个事件,此正则表达式将不起作用。
    • @Rawing 确实,有目共睹
    • @Rawing 可能可以use a lookahead like this
    • @bobblebubble 不错!
    【解决方案2】:

    输入几个单词边界,这将匹配它。

    (?s)\bhello\b(?:(?!\b(?:hello|bye)\b).)*\bapple\b.*?\bbye\b

    解释

     (?s)                 # Modifier: dot-all
     \b hello \b          # 'hello
     (?:
          (?!
               \b 
               (?: hello | bye )    # Not 'hello' nor 'bye'
               \b 
          )
          . 
     )*
     \b apple \b          # 'apple'
     .*?                  # the rest (note - this could match hello again)
     \b bye \b            # 'bye'
    

    【讨论】:

      猜你喜欢
      • 2014-01-07
      • 1970-01-01
      • 2019-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多