繁体   English   中英

检查字符串是否有日期,任何格式

[英]Check if string has date, any format

如何检查字符串是否可以解析为日期?

  • 1990年1月19日
  • 1990年1月19日
  • 1990年1月19日
  • 1990年1月19日
  • 90年1月19日
  • 1990
  • 1990年1月
  • 1990年1月

这些都是有效日期。 如果担心第3项内容和上面的最后一项内容之间没有空格,可以通过在字母/字符和数字之间自动插入空格来轻松解决(如果需要)。

但首先,基础知识:

我尝试将其放在if statement

if datetime.strptime(item, '%Y') or datetime.strptime(item, '%b %d %y') or datetime.strptime(item, '%b %d %Y')  or datetime.strptime(item, '%B %d %y') or datetime.strptime(item, '%B %d %Y'):

但这在try-except块中,并不断返回如下内容:

16343 time data 'JUNE1890' does not match format '%Y'

除非满足if语句中的第一个条件。

需要澄清的是,我实际上并不需要日期的值-我只想知道日期是否正确。 理想情况下,应该是这样的:

if item is date:
    print date
else:
    print "Not a date"

有什么办法吗?

dateutils.parserparse函数能够将许多日期字符串格式解析为datetime对象。

如果您只是想知道某个特定字符串是否可以表示或包含有效日期,则可以尝试以下简单函数:

from dateutil.parser import parse

def is_date(string, fuzzy=False):
    """
    Return whether the string can be interpreted as a date.

    :param string: str, string to check for date
    :param fuzzy: bool, ignore unknown tokens in string if True
    """
    try: 
        parse(string, fuzzy=fuzzy)
        return True

    except ValueError:
        return False

然后您有:

>>> is_date("1990-12-1")
True
>>> is_date("2005/3")
True
>>> is_date("Jan 19, 1990")
True
>>> is_date("today is 2019-03-27")
False
>>> is_date("today is 2019-03-27", fuzzy=True)
True
>>> is_date("Monday at 12:01am")
True
>>> is_date("xyz_not_a_date")
False
>>> is_date("yesterday")
False

自定义解析

parse可能会将某些字符串识别为日期,而您不想将其视为日期。 例如:

  • 解析"12""1999"将返回代表当前日期的datetime对象,其中日期和年份替换了字符串中的数字

  • "23, 4""23 4"将被解析为datetime.datetime(2023, 4, 16, 0, 0)

  • "Friday"将返回将来最近的星期五的日期。
  • 同样, "August"对应于当前日期,月份更改为八月。

另外, parse不支持区域设置,因此无法识别英语以外的其他语言的星期或星期几。

通过使用自定义parserinfo类,可以在某种程度上解决这两个问题,该类定义了如何识别月份和日期名称:

from dateutil.parser import parserinfo

class CustomParserInfo(parserinfo):

    # three months in Spanish for illustration
    MONTHS = [("Enero", "Enero"), ("Feb", "Febrero"), ("Marzo", "Marzo")]

然后可以将此类的实例与parse一起使用:

>>> parse("Enero 1990")
# ValueError: Unknown string format
>>> parse("Enero 1990", parserinfo=CustomParserInfo())
datetime.datetime(1990, 1, 27, 0, 0)

如果要解析这些特定格式,则可以与一系列格式进行匹配:

txt='''\
Jan 19, 1990
January 19, 1990
Jan 19,1990
01/19/1990
01/19/90
1990
Jan 1990
January1990'''

import datetime as dt

fmts = ('%Y','%b %d, %Y','%b %d, %Y','%B %d, %Y','%B %d %Y','%m/%d/%Y','%m/%d/%y','%b %Y','%B%Y','%b %d,%Y')

parsed=[]
for e in txt.splitlines():
    for fmt in fmts:
        try:
           t = dt.datetime.strptime(e, fmt)
           parsed.append((e, fmt, t)) 
           break
        except ValueError as err:
           pass

# check that all the cases are handled        
success={t[0] for t in parsed}
for e in txt.splitlines():
    if e not in success:
        print e    

for t in parsed:
    print '"{:20}" => "{:20}" => {}'.format(*t) 

印刷品:

"Jan 19, 1990        " => "%b %d, %Y           " => 1990-01-19 00:00:00
"January 19, 1990    " => "%B %d, %Y           " => 1990-01-19 00:00:00
"Jan 19,1990         " => "%b %d,%Y            " => 1990-01-19 00:00:00
"01/19/1990          " => "%m/%d/%Y            " => 1990-01-19 00:00:00
"01/19/90            " => "%m/%d/%y            " => 1990-01-19 00:00:00
"1990                " => "%Y                  " => 1990-01-01 00:00:00
"Jan 1990            " => "%b %Y               " => 1990-01-01 00:00:00
"January1990         " => "%B%Y                " => 1990-01-01 00:00:00

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM