我正在尝试创建一个程序,该程序将通过正则表达式识别“美国日期”,出于某种原因,我一直在挑选所有日期,而不仅仅是美国风格的日期。有人可以看看我的代码并告诉我正则表达式在做什么吗?
我已经仔细阅读了re Python文档,精心制作了一个表达式,该表达式可以选择任何样式为MM-DD-YYYY的美式日期。
import shutil, os, re
date_pattern = re.compile(r"""^(.*?)
((0|1)?\d)-
((0|1|2|3)?\d)-
((19|20)\d\d)
(.*?)$
""", re.VERBOSE)
american_date_list = []
file_list = os.listdir('.\date_files')
for file in file_list:
american_date = date_pattern.search(file)
if american_date:
american_date_list.append(file)
以下是我的测试文件:
'02-25-1992 bermuda'
'21-07-1992 Utah'
'25-02-1992 atlanta'
'bahamas 12-15-1992'
我的期望是,我只会为列出的第一个和最后一个文件名获得一个匹配对象,但我一直为每个文件名获得一个匹配项。
我在正则表达式中做错什么了吗?
答案 0 :(得分:1)
我在正则表达式中做错了什么?
使用它。
严重。仅当没有其他合理的选择时,才应使用正则表达式。
Python有一个很好的用于处理日期和时间的标准库,并不是您喜欢使用箭头之类的库。
要做的不是代替正则表达式,
In [1]: import datetime
In [2]: datetime.datetime.strptime("1-12-2018", "%m-%d-%Y")
Out[2]: datetime.datetime(2018, 1, 12, 0, 0)
这可以让您有一个合法的约会日期。现在,尝试解析不存在的月份:
In [20]: datetime.datetime.strptime("13-12-2018", "%m-%d-%Y")
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-20-02e1071664f7> in <module>()
----> 1 datetime.datetime.strptime("13-12-2018", "%m-%d-%Y")
/usr/lib64/python3.6/_strptime.py in _strptime_datetime(cls, data_string, format)
563 """Return a class cls instance based on the input string and the
564 format string."""
--> 565 tt, fraction = _strptime(data_string, format)
566 tzname, gmtoff = tt[-2:]
567 args = tt[:6] + (fraction,)
/usr/lib64/python3.6/_strptime.py in _strptime(data_string, format)
360 if not found:
361 raise ValueError("time data %r does not match format %r" %
--> 362 (data_string, format))
363 if len(data_string) != found.end():
364 raise ValueError("unconverted data remains: %s" %
ValueError: time data '13-12-2018' does not match format '%m-%d-%Y'
因此,如果格式不合法,您会看到这将引发异常,您可以在代码中使用
。 strptime
也可以为您处理特殊日期
datetime.datetime.strptime("02-29-2018", "%m-%d-%Y") # throws
ValueError: day is out of range for month
答案 1 :(得分:0)
在第二行中,您具有以下匹配项:
^(.*?)
匹配'2
((0|1)?\d)-
匹配1-
((0|1|2|3)?\d)-
匹配07-
((19|20)\d\d)
匹配1992
(.*?)$
匹配Utah'
将\b
放在((0|1)?\d)
之前,以确保它在单词边界处开始匹配,因此不会在数字中间匹配。
^(.*?)\b((0|1)?\d)-((0|1|2|3)?\d)-((19|20)\d\d)(.*?)$