【问题标题】:my regex is not catching required pattern in text?我的正则表达式没有在文本中捕获所需的模式?
【发布时间】:2021-03-17 23:54:33
【问题描述】:

我正在尝试使用正则表达式提取持续时间,

示例文本,

text = "Google, Inc 09/19 - 09/20 CA, USA"

这里是我的正则表达式,

pattern = fr"""
(?:
  (
    \d\d(?:\.|\/)\d\d\d\d|
    (?:{months_abr})?
    (?:{months_exp})?
    (?:
      (?:[\s\.\/\-]?\d{{2,4}})
    )
  )\s*(?:\-|to|\s)\s*
  (
    \d\d(?:\.|\/)\d\d\d\d|
    (?:{months_abr})?
    (?:{months_exp})?
    (?:
      (?:[\s\.\/\-]?\d{{2,4}})
    )|
    current|present|till\s?\-?date|till\s?\-?now|till\s?\-?date|to\s\-?present|until\s?\-?now|till\s?\-?now
  )
)"""

find_all = re.findall(
    pattern, text, flags=re.MULTILINE | re.VERBOSE | re.IGNORECASE
)

我得到的输出,

[('/19', '09')]

【问题讨论】:

  • 预期输出是什么?
  • 这是我想要的输出,('09/19', '09/20')。我当前的正则表达式处理其他模式,例如(march 1996, april 2020),但我的正则表达式对于上述文本失败,我不知道为什么。
  • 我尝试对模式进行了一些优化,我认为this one 可以是您寻求的正则表达式。

标签: python python-3.x regex re


【解决方案1】:

你可以使用

pattern = fr"""
(?<!\d)                          # A position not immediately preceded with digit
(                                # Group 1
  (?:\d?\d[./])?\d\d(?:\d\d)?    # one or two digits and . or / (optionally), two or four digits
  |                              # or
  (?:{months_abr}|{months_exp}) [\s./-]? \d\d(?:\d\d)? # month, space/dot/slash/hyphen and then two/four digits
)                                # end of Group 1 
\s*(?:-|to)\s*                   # - or "to" enclosed with 0+ whitespaces
(                                # Group 2
    (?:\d?\d[./])?\d\d(?:\d\d)?  
  |
    (?:{months_abr}|{months_exp}) [\s./-]?\d\d(?:\d\d)?
  |
    current|present|(?:un)?till\s?-?(?:date|now|date)|to\s-?present # some alternatives denoting time
)
"""

请参阅Python demo。输出:[('09/19', '09/20')]

请参阅regex demo

注意:我决定使用 \d\d 而不是 \d{2} 来保持代码更短,因为在 f 字符串中您需要使用 {{}} 来定义文字花括号,它们使字符串看起来这里很丑。

【讨论】:

  • 这个正则表达式不适用于像3/2006-6/2007 这样的日期,我可以改变什么来匹配这个模式?
  • @user_12 将\d\d[./]\d\d(?:\d\d)? 更改为\d?\d[./]\d\d(?:\d\d)?。我还建议在开头添加(?&lt;!\d)。见this regex demo
  • 在两者之间我有一个像2017 - present(或)2015 - 2018这样的模式,请帮我抓住那个模式吗?我试过了,但不知道要改变什么。
  • @user_12 很简单,只要把日期匹配部分设为可选,比如(?:\d?\d[./])?\d\d(?:\d\d)?,见updated regex demo
  • 谢谢,能否请您在答案中更新一次,我看那里有点困惑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
相关资源
最近更新 更多