【问题标题】:Regex Capture Multiple Phrases after One正则表达式在一个之后捕获多个短语
【发布时间】:2013-10-13 06:53:29
【问题描述】:

我试图弄清楚如何让正则表达式捕获一堆仅在一件特定事物之后出现的项目。我为此使用 Python。一个这样的例子是使用文本B <4>.<5> <6> A <1> m<2> . <3>,目的是只捕获 1、2 和 3。我认为像 A.*?<(.+?)> 这样的正则表达式会起作用,但它只使用 Python @987654324 捕获最后的 3 @。我可以得到任何帮助吗?

【问题讨论】:

  • 您是想将 1、2 和 3 捕获为单独的组还是包含所有这些组的一组?
  • Python regex multiple groups 的可能重复项
  • 对我来说没关系,但我最初是想把它们分成不同的组。

标签: python regex


【解决方案1】:

regex module(将在未来的 python 中替换 re)支持变量后视,这使得它相当容易:

s = "B <4>.<5> <6> A23 <1> m<2> . <3>"

import regex
print regex.findall(r'(?<=A\d+.*)<.+?>', s)
# ['<1>', '<2>', '<3>']

(我使用A\d+ 而不仅仅是A 让事情变得有趣)。如果你被绑定到股票re,你就不得不像这样丑陋的变通方法:

import re
print re.findall(r'(<[^<>]+>)(?=(?:.(?!A\d+))*$)', s)
# ['<1>', '<2>', '<3>']

或预分割:

print re.findall(r'<.+?>', re.split(r'A\d+', s)[-1])

【讨论】:

    【解决方案2】:

    使用可变宽度后视会更容易,但另一种方法可能是确保在您匹配的部分之后没有A,以便您可以使用以下内容:

    re.findall(r'<(.+?)>(?![^A]*A[^A]*$)', 'B <4>.<5> <6> A <1> m<2> . <3>')
    

    但这里有一个问题...(.+?) 接受 任何 可能会破坏您正在寻找的东西。您可以使用否定类:[^&gt;]+ 而不是 .+?

    这意味着:

    re.findall(r'<([^>]+)>(?![^A]*A[^A]*$)', 'B <4>.<5> <6> A <1> m<2> . <3>')
    

    regex101 demo

    (?![^A]*A[^A]*$) 确保在您捕获的部分前面没有A

    (?! ... ) 是一个负前瞻,如果匹配里面的内容,则匹配失败。

    [^A]* 匹配除A 之外的任何字符

    $ 匹配字符串的结尾。

    【讨论】:

      【解决方案3】:

      就目前而言,您的代码匹配&lt;&gt; 之间的文本,该文本位于A 之后,后跟零个或多个字符。此外,您的文本中唯一满足此条件的部分是 &lt;1&gt;(这就是返回的全部内容的原因)。

      有很多方法可以解决这个问题,但我认为最直接的方法是先拆分A,然后使用&lt;(.+?)&gt;

      >>> from re import findall, split
      >>> text = 'B <4>.<5> <6> A <1> m<2> . <3>'
      >>> text = split('A', 'B <4>.<5> <6> A <1> m<2> . <3>')
      >>> text
      ['B <4>.<5> <6> ', ' <1> m<2> . <3>']
      >>> text = text[1]
      >>> text
      ' <1> m<2> . <3>'
      >>> text = findall('<(.+?)>', text)
      >>> text
      ['1', '2', '3']
      >>>
      

      以上是一步一步的演示。以下是您想要的代码:

      >>> text = 'B <4>.<5> <6> A <1> m<2> . <3>'
      >>> findall('<(.+?)>', split('A', text)[1])
      ['1', '2', '3']
      >>>
      

      【讨论】:

      • 不是反过来吗? (?.+) 而不是 (.+?) ?我认为您正在尝试进行“非贪婪”搜索。我对吗?。编辑:你是对的。根据 Python 的参考,它是 (.+?)。
      • 没有。我说的方式使它成为非贪婪匹配。
      • @RobsonFrança (?.+) 不是有效的正则表达式。 (?:.+) 可能,但不是(?.+)
      猜你喜欢
      • 1970-01-01
      • 2021-10-29
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      • 2018-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多