因此,在我的Python脚本中,我打开了一个文本文件,其中包含的日期格式为“1991年1月26日”
下面是我的正则表达式:
pattern = """
(?:(September|April|June|November),\ (0?[1-9]|[12]\d|30),\ ((?:19|20)\d\d))#Months with 30 days
|(?:(January|March|May|July|August|October|December),\ (0?[1-9]|[12]\d|3[01]),\ ((?:19|20)\d\d))#Months with 31 days
|(?:February, (?:(?:(0?[1-9]|1\d|2[0-8]),\ ((?:19|20)\d\d))|(?:(29),\ ((?:(?:19|20)(?:04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96))|2000))))#February with 28 days or 29 with a leap year
"""
r = re.compile(pattern, re.VERBOSE)此正则表达式应匹配任何实际日期,包括闰年的2月29日。
我遇到的问题是找出一种方法来浏览我打开的文本文件,并将所有匹配的日期放入一个列表中。我尝试过使用.match,.search,.split和其他的工具,但是我没有任何的运气。有没有办法把所有的匹配项都作为一个字符串放到一个列表中,这样我就可以很容易地将这个列表与另一个列表进行比较,并找到两个列表中的所有日期?基本上,我想要一个列表出来,看起来像这样
“1990年1月1日”,“2012年2月29日”,“1945年12月25日”,....
另外,请让我知道我的正则表达式是否正确。我修改了另一个问题的答案,我不确定我是否正确,因为我不能看到我的文本文件中的日期是否匹配。
发布于 2012-04-25 13:54:02
在你尝试过的事情列表中,你没有提到re.findall()。这将为您提供所有正则表达式匹配的列表。
但是,您需要使用所有非捕获组(?:...),否则您将获得所有匹配组的列表(...)。因此,我建议
pattern = """
(?:September|April|June|November)
,[ ]
(?:0?[1-9]|[12]\d|30)
,[ ]
(?:19|20)\d\d # Months with 30 days
|
(?:January|March|May|July|August|October|December)
,[ ]
(?:0?[1-9]|[12]\d|3[01])
,[ ]
(?:19|20)\d\d # Months with 31 days
|
February
,[ ]
(?:
(?:0?[1-9]|1\d|2[0-8])
,[ ]
(?:19|20)\d\d
|
29
,[ ]
(?:
(?:19|20)
(?:04|08|12|16|20|24|28|32|36|40|44|48|
52|56|60|64|68|72|76|80|84|88|92|96)
|
2000
)
) # February with 28 days or 29 with a leap year"""但是,您真的需要验证日期的正确性吗?您是否希望像February, 31, 2000这样的错误日期出现在您的数据中?如果没有,您可以极大地简化您的正则表达式。或者至少将日期验证委托给一个日期解析函数,该函数比庞大的正则表达式更适合这项任务。
例如:
pattern = """
(?:January|February|March|April|May|June|
July|August|September|October|November|December)
,[ ]
[0-3]?\d
,[ ]
(?:19|20)\d\d
"""匹配像January, 0, 1999或February, 31, 2000这样的胡言乱语,但这真的重要吗?
发布于 2012-09-16 17:29:06
您可以使用简单的正则表达式进行预处理,并使用datetime.strptime()函数验证日期:
import re
from datetime import datetime
def extract_date_strings(text):
return filter(valid_date, re.findall(r"[A-Z][a-z]+, \d\d?, \d{4}", text))
def valid_date(datestr):
try:
return datetime.strptime(datestr, "%B, %d, %Y") #note: locale dependent
except ValueError:
return None您可以使用此代码将测试结果与您的代码进行比较。
示例
print extract_date_strings('''"January, 1, 1990", "February, 29, 2012",
"December, 25, 1945"
May, 40, 1945 Not a Month, 20, 1945
February, 29, 2000 February, 29, 1900
May, 1, 199
''')输出
['January, 1, 1990', 'February, 29, 2012', 'December, 25, 1945',
'February, 29, 2000']发布于 2012-04-25 14:39:39
随机思考:
如果您需要询问您的正则表达式是否正确,那就太复杂了。
re.VERBOSE的想法是使您的正则表达式清晰易读,而不是附加任何隐藏的明显注释。如果你看到水平滚动条,你的废话太长了。
如果findall不存在,您可以编写一个循环,该循环将使用search查找下一个匹配项,并使用match_object.end()查找search的pos参数
def myfindall(regex, strg):
alist = []
pos = 0
while True:
m = regex.search(strg, pos)
if not m: break
alist.append(m.group(0))
pos = m.end()
return alist您确定月份名称后应该有一个逗号吗?
https://stackoverflow.com/questions/10310023
复制相似问题