【问题标题】:Extract string between 2 strings and fetch to the end if 2nd string not found提取 2 个字符串之间的字符串,如果未找到第 2 个字符串,则提取到末尾
【发布时间】:2018-05-16 14:06:53
【问题描述】:

如果没有找到第二个字符串,在 2 个字符串之间提取字符串并提取到末尾的模式是什么?例如:检索分配给 foo 的值(值包含空格)


import re

s1 = 'quz=1, 2, 3 and foo=4, 5, 6 and bar=7, 8, 9'
m = re.match(pattern=r'^.*foo=(.*)\sand', string=s1)

assert m.group(1) == '4, 5, 6'

s2 = 'quz=1, 2, 3 and foo=4, 5, 6'
m = re.match(pattern=r'^.*foo=(.*)', string=s2)

assert m.group(1) == '4, 5, 6'

谢谢

【问题讨论】:

  • r'^.*foo=(.+?)(?:\sand|$)' 可以通过使 and 可选匹配来工作
  • 您也可以使用r'foo=((?:(?! and).)*)',但效率不高。另一种选择是r'foo=(\S*(?:\s(?!and)\S*)*)'
  • 感谢 anubhava,它奏效了。顺便说一句,您为什么将 foo=(.*) 更改为 foo=(.+?) ?塔
  • @CanLu:这是因为.* 是贪婪的,会尝试匹配最长的字符串直到字符串结尾。所以r'^.*foo=(.*?)(?:\sand|$)' 也可以。

标签: python regex python-2.7


【解决方案1】:

您可以使用 look ahead (?=...) 逻辑(下一个 and 或字符串结尾 $):

由于不是从字符串的开头匹配,使用re.search 可能更方便;如果您只想匹配下一个and,非贪婪的.*? 正则表达式更适合;

import re
re.search(r'foo=(.*?)(?= and|$)', s1).group(1)
# '4, 5, 6'
re.search(r'foo=(.*?)(?= and|$)', s2).group(1)
# '4, 5, 6'

【讨论】:

    【解决方案2】:

    您的正则表达式需要允许带有 lazy 量词的 and字符串结尾。在您的正则表达式中,.*greedy 并且会尝试匹配最长的字符串直到字符串结尾。

    以下正则表达式应该适合您:

    r'^.*foo=(.*?)(?:\sand|$)'
    

    这里是完整的代码:

    >>> s1 = 'quz=1, 2, 3 and foo=4, 5, 6 and bar=7, 8, 9'
    >>> s2 = 'quz=1, 2, 3 and foo=4, 5, 6'
    >>> p = r'^.*foo=(.*?)(?:\sand|$)'
    
    >>> print re.findall(p, s1)
    ['4, 5, 6']
    
    >>> print re.findall(p, s2)
    ['4, 5, 6']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-04
      • 1970-01-01
      • 2016-08-20
      • 2021-01-23
      • 1970-01-01
      • 2023-02-23
      • 1970-01-01
      相关资源
      最近更新 更多