我正在尝试获取最近12个小时的所有文件, 文件名具有以下格式%Y-%m-%d%H
这是我的python脚本,我正在努力工作
last12HourDateTime = datetime.today() - timedelta(hours = 12)
allowedFormat = last12HourDateTime.strftime('%Y-%m-%d %H')
for filePath in glob.glob(allowedFormat):
我知道有很多方法可以做到,但我想知道它是否可能这样
(编辑) 我能够通过
完成它allowedFormats =[]
for i in range (1,12):
last12HourDateTime = datetime.today() - timedelta(hours = (i - 1))
allowedFormats.append(last12HourDateTime.strftime('%Y-%m-%d-%H.log'))
for allowedFormat in allowedFormats:
for filePath in glob.glob(allowedFormat):
但仍在寻找更有效的解决方案
答案 0 :(得分:4)
技术上:是的。
值得:不。
原因:正则表达式不了解数值,因此无法进行算术比较(x> z - 12)。
换句话说:你必须为每一次使用生成一个自定义正则表达式,因此使用真正的日期格式解析器和一个能够完成你所能完成的日期类的方法会更好。正则表达式你必须生成大量的AND
ed (...|...)
组,并且最终会进行基本的批量字符串比较(这仍然是有效的正则表达式,但缺乏任何更高的目的)。
模式的大多数与文字相关的问题“正则表达式中是否可能x?”在技术上可以用 YES 来回答。 (见上文)
因此我更愿意问:“我应该(尝试)用正则表达式执行x吗?”或“正则表达式是x的正确工具吗?”。
如果你唯一的工具是锤子......
如果你想至少缩小潜在匹配列表(在进行任何实际算术算法之前),你必须根据这些规则生成一个正则表达式(从头顶开始,无保证)
(我将h
用于当前时间,d
用于当天,m
用于当前月份,y
用于当前年度。)
if (h < 12)
%dh = '(?:yesterday (?:1[2-9]|2[0-3])|today [0-9]{1,2})'
else
%dh = '(?:tomorrow (?:[0-9]|1[0-1])|today [0-9]{1,2})'
if (d == 1)
%m = '(?:lastmonth|thismonth)'
else if (d == 31 && count of days in m == 31 ||
d == 30 && count of days in m == 30 ||
m == 2 && d == 28 ||
m == 2 && d == 29 && y is leap year)
%m = '(?:thismonth|nextmonth)'
else
%m = 'thismonth'
if (m == 1)
%y = '(lastyear|thisyear)'
else if (m == 12)
%y = '(?:thisyear|nextyear)'
else
%y = 'thisyear'
您可以使用各自的数值替换yesterday
,thisyear
等。
并形成模式%y-%m-%dh
的正则表达式,您可以使用上面确定的值替换%y
,%m
,%dh
。
再次:日期算术很棘手,因此我的算法可能包含错误。
我不知道你问题的更广泛背景,所以我只能猜测。 根据您提供的信息(假设每次搜索文件名/文件不会改变100%,从而允许某种程度的缓存),我可能会这样做:
枚举您的文件列表并将其日期格式的文件名转换为UNIX时间戳,将它们中的每一个添加到列表中(可能更好:创建容纳时间戳和文件路径的容器对象,否则您必须通过以下方式验证文件路径:将时间戳转换回日期格式化字符串,并要求层次结构为平面。对列表进行排序。使用修改后的二进制搜索获取匹配文件的范围(其中不是搜索实际值匹配,而是搜索一系列相对匹配。我现在没有示例代码,但这并不困难。)
现在假设有时添加/删除文件,您必须能够监控这些系统事件并更新列表。
第一次创建列表需要O(n)
(+ O(nlogn)
进行排序),但是如果您能够巧妙地更新缓存的时间戳列表,那么您应该能够获得相当高的性能。< / p>