6

我正在使用 dateutil 来解析图片文件名并根据日期对其进行排序。由于不是我所有的图片都有元数据,dateutil 试图猜测将它们放在哪里。

我的大部分图片都是这种格式:2007-09-10_0001.jpg 2007-09-10_0002.jpg 等等...

fileName = os.path.splitext(file)[0]
print("Guesssing date from ", fileName)
try:
    dateString = dateParser.parse(file, fuzzy=True)
    print("Guessed date", dateString)
    year=dateString.year
    month = dateString.month
    day=dateString.day
except ValueError:
    print("Unable to determine date of ", file)

我得到的回报是这样的:

('Guesssing date from ', '2007-09-10_00005')
('Unable to determine date of ', '2007-09-10_00005.jpg')

现在我应该能够从下划线之后删除所有内容,但如果可能的话,我想要一个更强大的解决方案,以防我有其他格式的图片。我虽然模糊会尝试在字符串中找到任何日期并与之匹配,但显然不起作用......

有没有一种简单的方法可以让解析器找到任何看起来像日期的东西并在此之后停止?如果不是,那么强制解析器忽略下划线之后的所有内容的最简单方法是什么?或者一种使用忽略部分定义多种日期格式的方法。

谢谢!

4

2 回答 2

4

只要您无法解码,您就可以尝试“减少”字符串:

from dateutil import parser

def reduce_string(string):
    i = len(string) - 1
    while string[i] >= '0' and string[i] < '9':
        i -= 1
    while string[i] < '0' or string[i] > '9':
        i -= 1
    return string[:i + 1]

def find_date(string):
    while string:
        try:
            dateString = parser.parse(string, fuzzy=True)
            year = dateString.year
            month = dateString.month
            day = dateString.day
            return (year, month, day)
        except ValueError:
            pass

        string = reduce_string(string)

    return None

date = find_date('2007-09-10_00005')
if date:
    print date
else:
    print "can't decode"

这个想法是删除字符串的结尾(任何数字,然后是任何非数字),直到解析器可以将其解码为有效日期。

于 2013-06-09T17:14:08.973 回答
3

在这里评论未来,作为对这个问题的一些更深入的了解。

虽然dateutil的模糊搜索非常擅长以普通自然语言获取日期,但它在上面的字符串中却失败了,其中包含大量与数字/符号相关的噪音。但是,对于更新版本的dateutil,在运行时:

>>> from dateutil.parser import parse
>>> parse('2007-09-10_00005.jpg', fuzzy=True)

parse失败TypeError: 'NoneType' object is not iterable,这不是很地道。

另一种选择是简单地使用正则表达式查找已知的日期格式。当然,这因用例而异,但 OP 提到他的日期始终采用 format YYYY-MM-DD,这使其成为正则表达式搜索的理想选择:

from dateutil.parser import parse
import re

date_pattern = re.compile('\d{4}-\d{2}-\d{2}')

def extract_date(filename):
    matches = re.match(date_pattern, filename)
    if matches:
        return parse(matches.group(0))
    else:
        return None

extract_date('2007-09-10_00005.jpg')  # datetime.datetime(2007, 9, 10, 0, 0)
于 2014-08-21T09:59:52.860 回答