正则表达式从日期范围中提取两个日期

时间:2016-09-26 18:12:31

标签: python regex

我有一个日期范围,我想提取两个日期,这是一个示例字符串:

Sep 25-28, 2016

我希望有两个正则表达式,一个匹配:

Sep 25, 2016

和另一个匹配:

Sep 28, 2016

但是那时我也喜欢这样:

Sep 29-Oct 2, 2016

这是我到目前为止所建立的:

(?P<date>\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec|[0-9]|1[0-2]) (\d|[0-2][0-9]|3[0-1])(\s|\.|-)(:?\d|[0-2][0-9]|3[0-1]),?(\s|\.|-)\b\d{1,4}\b)

但当然要匹配整个范围。

任何帮助?

2 个答案:

答案 0 :(得分:1)

查看您的示例范围,看起来他们遵循以下模式:

BEGIN_MONTH SPACE BEGIN_DAY DASH END_MONTH (optional) END_DAY COMMA SPACE YEAR

由此,您想要生成两个字符串:

BEGIN_MONTH SPACE BEGIN_DAY COMMA SPACE YEAR

END_MONTH (if present; otherwise use BEGIN_MONTH) SPACE END_DAY COMMA SPACE YEAR

这是对的吗?如果日期范围跨越一年边界,您是否需要考虑开始和结束年份?

import re

pattern = '(\w+) (\d+)-(\w+ )?(\d+), (\d+)'
pc = re.compile(pattern)

text = 'Sep 25-Oct 5, 2016'
# text = 'Sep 25-29, 2016' -- also works in this format

if pc.match(text).group(3):
    # second month name is present
    print ('%s %s-%s%s, %s' % (pc.match(text).group(1),
                                pc.match(text).group(2),
                                pc.match(text).group(3),
                                pc.match(text).group(4),
                                pc.match(text).group(5)))

else:
    print ('%s %s-%s %s, %s' % (pc.match(text).group(1),
                                pc.match(text).group(2),
                                pc.match(text).group(1),
                                pc.match(text).group(4),
                                pc.match(text).group(5)))

答案 1 :(得分:0)

我建议为每种可能性使用不同的正则表达式,并按顺序测试它们。这将导致更简单的程序(带有测试用例)。否则,正则表达式将是可怕的。

import re

RE1 = re.compile(r"(\w+)\s*(\d+)\,\s+(\d+)")  # Month day, year                              
RE2 = re.compile(r"(\w+)\s*(\d+)\-(\d+)\,\s+(\d+)")  # Month day-day, year                   
RE3 = re.compile(r"(\w+)\s*(\d+)\-(\w+)\s+(\d+)\,\s+(\d+)")  # Month day - Month day, year                                                                                                   


def date_interval(t):
  match1 = RE1.match(t)
  match2 = RE2.match(t)
  match3 = RE3.match(t)
  if match1:
    month1 = month2 = match1.group(1)
    day1 = day2 = match1.group(2)
    year = match1.group(3)
  elif match2:
    month1 = month2 = match2.group(1)
    day1 = match2.group(2)
    day2 = match2.group(3)
    year = match2.group(4)
  elif match3:
    month1 = match3.group(1)
    day1 = match3.group(2)
    month2 = match3.group(3)
    day2 = match3.group(4)
    year = match3.group(5)
  else:
    month1 = month2 = day1 = day2 = year = ''
  return ( day1, month1, day2, month2, year )


texts = (
  'Sep 25, 2016',
  'Oct 12-23, 2017',
  'Jan 15-Feb 26, 2018',
)

for t in texts:
  print t, date_interval(t)

这打印(python2)

Sep 25, 2016 ('25', 'Sep', '25', 'Sep', '2016')
Oct 12-23, 2017 ('12', 'Oct', '23', 'Oct', '2017')
Jan 15-Feb 26, 2018 ('15', 'Jan', '26', 'Feb', '2018')

如果您需要解析不同年份的日期,则可以轻松扩展该程序。

您也可以将\w替换为月份,就像您在帖子中所做的那样(Jan|Feb|...)。