将日期从可读字符串转换为更标准

时间:2014-02-16 02:38:07

标签: python regex replace

我的日期格式为Fri 27th Aug,这是一个噩梦,我确信你可以想象。

我想知道如何最好地将这些转换为美国日期格式08/27/13。我需要指定月份中的年份,即8月至12月暗示13,1月至7月暗示14

我正在考虑在正则表达式中查找如何执行此操作,或者甚至只是进行一系列字符串替换。

但复杂的是我有一个字符串列表,而不是所有字符串的日期。如果其他人在里面有数字,我该如何测试这个表格的日期,然后替换它?

e.g。

list = ['not a date', 'als0 not a dat3', 'Wed 5th Jan', ... , 'no date here']

测试的要求使正则表达式看起来合适,但我已经在Python上阅读了很多反对在Python中使用re,但我不知道为什么。我应该(学会使用,并且)使用它吗?

通过@ Allan的回答,我已经能够通过以下方式解决我的问题:

def is_date(string):
    tmp = string.replace('th','')
    string = tmp.replace('rd','')
    tmp = string.replace('nd','')
    string = tmp.replace('st','')
    try:
        d = strptime(string, "%a %d %b")
        date = str(d[1]) + "/" + str(d[2]) + "/"
        if d[1] >= 8:
            date += "13"
        else:
            date += "14"
        return date
    except ValueError:
        return 0

感谢您的回答,@ Allan,@ adadmith和@codnodder。

3 个答案:

答案 0 :(得分:2)

看看time.strptime。它会引发ValueError,因此您可能希望捕获该异常并忽略非日期的字符串。

在这种情况下我会避免使用正则表达式,因为日期格式化会变得相当复杂。你需要指定可能的月份和工作日缩写,检查案例变化......你真的,真的不想去那里,如果你需要的只是解决一个简单明确的问题:)

@OllieFord:改进你的新代码,我到达了:

import datetime

def is_date(string):
    for suffix in ("th", "rd", "nd", "st"):
        string = string.replace(suffix, "")

    try:
        d = datetime.datetime.strptime(string, "%a %d %b")
        y = 2014
        if d.month >= 8:
            y = 2013            
        d = d.replace(year = y)
        return d.strftime("%x")
    except ValueError:
        return None

它使用datetime类中的函数来避免手动工作。请注意在转换为字符串时使用%x:它将使用您当前的区域设置来格式化日期。这可能是你想要的,也可能不是......

我还要看看@Marian提到的Dateutil.parser。如果你不关心添加一个外部依赖,它似乎也解决了这个问题,也许更容易(我还没试过)。

答案 1 :(得分:1)

答案 2 :(得分:1)

正则表达式似乎不是这个特定任务的最坏想法。以下是一个很长的例子。我相信有更多有效的方法。

import re

# Convert dates like "Fri 27th Aug" with year fudge
mons = {
    'Aug' : ( 8, 13),
    'Sep' : ( 9, 13),
    'Oct' : (10, 13),
    'Nov' : (11, 13),
    'Dec' : (12, 13),
    'Jan' : ( 1, 14),
    'Feb' : ( 2, 14),
    'Mar' : ( 3, 14),
    'Apr' : ( 4, 14),
    'May' : ( 5, 14),
    'Jun' : ( 6, 14),
    'Jul' : ( 7, 14),
}
days = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')

# pattern is purposefully strict to avoid false matches against
# other arbitrary strings
pat = re.compile(r'^(%s) (\d+)(st|nd|rd|th) (%s)$' %
                 ('|'.join(days), '|'.join(mons.keys())))
strlist = ['not a date', 'als0 not a dat3', 'Wed 5th Jan', 'no date here']
newlist = []
for tok in strlist:
    m = re.match(pat, tok)
    if m:
        day = int(m.group(2))
        mon = m.group(4)
        newlist.append('%02d/%02d/%02d' % (mons[mon][0], day,mons[mon][1]))
    else:
        newlist.append(tok)

for tok in newlist:
    print tok

编辑:更改日期格式以匹配OP更正。