Python:使用格式将字符串解析为日期

Python:使用格式将字符串解析为日期,python,regex,date,Python,Regex,Date,用户可以输入字符串,该字符串包含以下格式的日期MM/DD/YY或MM/DD/YYYY。有没有有效的方法从字符串中提取日期?我正在考虑将正则表达式用于\d+\/\d+\/\d+。我还希望能够排序的日期。也就是说,如果字符串包含8/17/15和08/16/2015,它将首先列出8/16日期,然后列出8/17日期,如果可以使用,为什么还要麻烦使用regex?如果可以使用,为什么要麻烦使用regex?您也可以尝试strtime: import time dates = ('08/17/15', '8/

用户可以输入字符串,该字符串包含以下格式的日期
MM/DD/YY
MM/DD/YYYY
。有没有有效的方法从字符串中提取日期?我正在考虑将正则表达式用于
\d+\/\d+\/\d+
。我还希望能够排序的日期。也就是说,如果字符串包含
8/17/15
08/16/2015
,它将首先列出8/16日期,然后列出8/17日期,如果可以使用,为什么还要麻烦使用regex?

如果可以使用,为什么要麻烦使用regex?

您也可以尝试strtime:

import time

dates = ('08/17/15', '8/16/2015')

for date in dates:
    print(date)
    ret = None
    try:
        ret = time.strptime(date, "%m/%d/%Y")
    except ValueError:
        ret = time.strptime(date, "%m/%d/%y")
    print(ret)

更新

评论后更新:

这样,如果无法解析日期,您将返回有效日期或
None

import time

dates = ('08/17/15', '8/16/2015', '02/31/15')

for date in dates:
    print(date)
    ret = None
    try:
        ret = time.strptime(date, "%m/%d/%Y")
    except ValueError:
        try:
            ret = time.strptime(date, "%m/%d/%y")
        except ValueError:
            pass
    print(ret)

更新2

在关于需求的评论之后,再进行一次更新

这是一个版本(它只考虑日期;不考虑前后文本。但使用regex组可以轻松提取):

重新导入
导入时间
日期=('foo 1 08/17/15'、'8/16/2015酒吧2'、'foo 3 02/31/15酒吧4')
对于日期中的日期:
打印(日期)
匹配=重新搜索(“(?P[0-9]+/[0-9]+/[0-9]+)”,日期)
日期\u str=match.group('date')
ret=无
尝试:
ret=time.strtime(日期“%m/%d/%Y”)
除值错误外:
尝试:
ret=time.strtime(日期“%m/%d/%y”)
除值错误外:
通过
打印(ret)

您也可以尝试strtime:

import time

dates = ('08/17/15', '8/16/2015')

for date in dates:
    print(date)
    ret = None
    try:
        ret = time.strptime(date, "%m/%d/%Y")
    except ValueError:
        ret = time.strptime(date, "%m/%d/%y")
    print(ret)

更新

评论后更新:

这样,如果无法解析日期,您将返回有效日期或
None

import time

dates = ('08/17/15', '8/16/2015', '02/31/15')

for date in dates:
    print(date)
    ret = None
    try:
        ret = time.strptime(date, "%m/%d/%Y")
    except ValueError:
        try:
            ret = time.strptime(date, "%m/%d/%y")
        except ValueError:
            pass
    print(ret)

更新2

在关于需求的评论之后,再进行一次更新

这是一个版本(它只考虑日期;不考虑前后文本。但使用regex组可以轻松提取):

重新导入
导入时间
日期=('foo 1 08/17/15'、'8/16/2015酒吧2'、'foo 3 02/31/15酒吧4')
对于日期中的日期:
打印(日期)
匹配=重新搜索(“(?P[0-9]+/[0-9]+/[0-9]+)”,日期)
日期\u str=match.group('date')
ret=无
尝试:
ret=time.strtime(日期“%m/%d/%Y”)
除值错误外:
尝试:
ret=time.strtime(日期“%m/%d/%y”)
除值错误外:
通过
打印(ret)
您可以使用熊猫的日期

import pandas as pd

timestr = ['8/8/95', '8/15/2014']
>>> [pd.datetools.parse(d) for d in timestr]
[datetime.datetime(1995, 8, 8, 0, 0), datetime.datetime(2014, 8, 15, 0, 0)]
你可以使用熊猫的日期

import pandas as pd

timestr = ['8/8/95', '8/15/2014']
>>> [pd.datetools.parse(d) for d in timestr]
[datetime.datetime(1995, 8, 8, 0, 0), datetime.datetime(2014, 8, 15, 0, 0)]

为什么不使用
strtime
将它们存储为
datetime
对象呢。这些对象可以很容易地通过这种方式进行比较和排序

import datetime
try:
    date = datetime.datetime.strptime("08/03/2015", "%m/%d/%Y")
except:
    date = datetime.datetime.strptime("08/04/15", "%m/%d/%y")
finally:
    dateList.append(date)
注意
%Y
%Y
之间的区别。然后,您可以比较用这种方法制作的日期,看看哪些日期更大或更少。您还可以使用
dateList.sort()对其进行排序

如果要将日期再次作为字符串,可以使用:

>>> dateString = date.strftime("%Y-%m-%d")
>>> print dateString
'2015-08-03'

为什么不使用
strtime
将它们存储为
datetime
对象呢。这些对象可以很容易地通过这种方式进行比较和排序

import datetime
try:
    date = datetime.datetime.strptime("08/03/2015", "%m/%d/%Y")
except:
    date = datetime.datetime.strptime("08/04/15", "%m/%d/%y")
finally:
    dateList.append(date)
注意
%Y
%Y
之间的区别。然后,您可以比较用这种方法制作的日期,看看哪些日期更大或更少。您还可以使用
dateList.sort()对其进行排序

如果要将日期再次作为字符串,可以使用:

>>> dateString = date.strftime("%Y-%m-%d")
>>> print dateString
'2015-08-03'

使用正则表达式组,我们可以得到如下结果:

import re
ddate = '08/16/2015'

reg = re.compile('(\d+)\/(\d+)\/(\d+)')
matching = reg.match(ddate)
if matching is not None:
    print(matching.groups())
会让步

('08','16','2015')
您可以在之后解析它,但是如果您想从可以使用的第一个位置除去前导0,那么

reg = re.compile('0*(\d+)\/0*(\d+)\/(\d+)')

使用正则表达式组,我们可以得到如下结果:

import re
ddate = '08/16/2015'

reg = re.compile('(\d+)\/(\d+)\/(\d+)')
matching = reg.match(ddate)
if matching is not None:
    print(matching.groups())
会让步

('08','16','2015')
您可以在之后解析它,但是如果您想从可以使用的第一个位置除去前导0,那么

reg = re.compile('0*(\d+)\/0*(\d+)\/(\d+)')
看看,它是一个内置函数,知道如何从字符串创建datetime对象。它接受要转换的字符串并写入日期

from datetime import datetime

def str_to_date(string):
    pattern = '%m/%d/%Y' if len(string) > 8 else '%m/%d/%y'
    try:
        return datetime.strptime(string, pattern).date()
    except ValueError:
        raise  # TODO: handle invalid input
函数返回一个对象,该对象可以直接与其他
date()
对象进行比较(例如排序时)

用法:

>>> d1 = str_to_date('08/13/2015')
>>> d2 = str_to_date('08/12/15')
>>> d1
datetime.date(2015, 8, 13)
>>> d2
datetime.date(2015, 8, 12)
>>> d1 > d2
True
使现代化 OP在一篇评论中解释说,诸如
'foo 08/13/2015 bar'
之类的字符串不应该自动丢弃,应该从中提取日期

为此,我们必须首先在用户输入中搜索候选字符串:

import re
from datetime import date

user_string = input('Enter something')  # use raw_input() in Python 2.x

pattern = re.compile(r'(\d{2})/(\d{2})/(\d{4}|\d{2})')  # 4 digits match first!
match = re.search(pattern, user_string)

if not match:
    d = None
else:
    month, day, year = map(int, match.groups())
    try:
        d = date(year, month, day)
    except ValueError:
        d = None  # or handle error in a different way

print(d)
代码读取用户输入,然后尝试在其中查找一个模式,该模式表示
MM/DD/YYYY
MM/DD/YY
格式的日期。请注意,最后一个捕获组(在括号中,即
()
)检查四位或两位连续数字

如果它找到一个候选日期,它将解压匹配中的捕获组,同时将它们转换为整数。然后,它使用三个匹配的片段尝试创建一个新的
date()
对象。如果失败,则候选人日期无效,例如
'02/31/2015'

脚注:

  • 代码将只捕获输入中的第一个日期候选项
  • 所使用的正则表达式的当前形式也将匹配输入中的日期,如“12308/13/2015123”。如果不希望这样做,则必须对其进行修改,可能需要添加一些先行/后顾断言
看看,这是一个内置函数,知道如何从字符串创建datetime对象。它接受要转换的字符串并写入日期

from datetime import datetime

def str_to_date(string):
    pattern = '%m/%d/%Y' if len(string) > 8 else '%m/%d/%y'
    try:
        return datetime.strptime(string, pattern).date()
    except ValueError:
        raise  # TODO: handle invalid input
函数返回一个对象,该对象可以直接与其他
date()
对象进行比较(例如排序时)

用法:

>>> d1 = str_to_date('08/13/2015')
>>> d2 = str_to_date('08/12/15')
>>> d1
datetime.date(2015, 8, 13)
>>> d2
datetime.date(2015, 8, 12)
>>> d1 > d2
True
使现代化 OP在一篇评论中解释说,诸如
'foo 08/13/2015 bar'
之类的字符串不应该自动丢弃,应该从中提取日期

为此,我们必须首先在用户输入中搜索候选字符串:

import re
from datetime import date

user_string = input('Enter something')  # use raw_input() in Python 2.x

pattern = re.compile(r'(\d{2})/(\d{2})/(\d{4}|\d{2})')  # 4 digits match first!
match = re.search(pattern, user_string)

if not match:
    d = None
else:
    month, day, year = map(int, match.groups())
    try:
        d = date(year, month, day)
    except ValueError:
        d = None  # or handle error in a different way

print(d)
代码读取用户输入,然后尝试在其中查找一个模式,该模式表示
MM/DD/YYYY
MM/DD/YY
格式的日期。请注意,最后一个捕获组(在p