【问题标题】:Python RegEx query missing overlapping substringsPython RegEx 查询缺少重叠的子字符串
【发布时间】:2013-09-01 01:48:18
【问题描述】:

Python3.3、OS X 7.5

我正在尝试查找定义如下的 4 字符子字符串的所有实例:

  • 第一个字符 = 'N'
  • 第二个字符 = 除了“P”之外的任何字符
  • 第三个字符 = 'S' 或 'T'
  • 第四个字符 = 除了“P”之外的任何字符

我的查询如下所示:

re.findall(r"\N[A-OQ-Z][ST][A-OQ-Z]", text)

除了在两个子字符串重叠的特殊情况下,这是有效的。该案例涉及以下 5 个字符的子字符串:

'...NNTSY...'

查询捕获第一个 4 个字符的子字符串 ('NNTS'),但不捕获第二个 4 个字符的子字符串 ('NTSY')。

这是我第一次尝试正则表达式,显然我遗漏了一些东西。

【问题讨论】:

    标签: regex string python-3.x


    【解决方案1】:

    如果重新引擎在匹配字符时不消耗字符,您可以这样做,这可以通过前瞻断言来实现:

    import re
    text = '...NNTSY...'
    for m in re.findall(r'(?=(N[A-OQ-Z][ST][A-OQ-Z]))', text):
        print(m)
    

    输出:

    NNTS
    NTSY
    

    让断言中的所有内容都有效,但也感觉很奇怪。另一种方法是将N 从断言中取出:

    for m in re.findall(r'(N(?=([A-OQ-Z][ST][A-OQ-Z])))', text):
        print(''.join(m))
    

    【讨论】:

      【解决方案2】:

      来自 Python 3 文档(已添加重点):

      $ python3 -c '重新导入;帮助(重新.findall)' 关于模块 re 中的 findall 函数的帮助: findall(模式,字符串,标志=0) 返回字符串中所有 非重叠 匹配项的列表。 如果模式中存在一个或多个捕获组,则返回 组列表;这将是一个元组列表,如果模式 有多个组。 结果中包含空匹配项。

      如果您想要重叠实例,请在循环中使用regex.search()。您必须编译正则表达式,因为非编译正则表达式的 API 不带参数来指定起始位置。

      def findall_overlapping(pattern, string, flags=0):
          """Find all matches, even ones that overlap."""
          regex = re.compile(pattern, flags)
          pos = 0
          while True:
              match = regex.search(string, pos)
              if not match:
                  break
              yield match
              pos = match.start() + 1
      

      【讨论】:

        【解决方案3】:
        (N[^P](?:S|T)[^P])
        

        Edit live on Debuggex

        【讨论】:

          猜你喜欢
          • 2012-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-01
          • 2017-09-18
          相关资源
          最近更新 更多