- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在发布此问题之前,我已经浏览了多个链接,因此请仔细阅读,下面是解决了我 90% 问题的两个答案:
parse multiple dates using dateutil
How to parse multiple dates from a block of text in Python (or another language)
问题:我需要在 Python 中解析多种格式的多个日期
上述链接的解决方案:我可以这样做,但仍然有某些格式我无法这样做。
仍然无法解析的格式有:
text ='我想在 5 月 16 日至 5 月 18 日期间访问'
text ='我想在 5 月 16 日至 18 日期间参观'
text ='我想从 2018 年 5 月 6 日起访问'
我也尝试过正则表达式,但由于日期可以采用任何格式,因此排除了该选项,因为代码变得非常复杂。因此,请建议我修改链接上提供的代码,以便也可以在同一链接上处理上述 3 种格式。
最佳答案
此类问题总是需要调整新的边缘情况,但以下方法相当稳健:
from itertools import groupby, izip_longest
from datetime import datetime, timedelta
import calendar
import string
import re
def get_date_part(x):
if x.lower() in month_list:
return x
day = re.match(r'(\d+)(\b|st|nd|rd|th)', x, re.I)
if day:
return day.group(1)
return False
def month_full(month):
try:
return datetime.strptime(month, '%B').strftime('%b')
except:
return datetime.strptime(month, '%b').strftime('%b')
tests = [
'I want to visit from May 16-May 18',
'I want to visit from May 16-18',
'I want to visit from May 6 May 18',
'May 6,7,8,9,10',
'8 May to 10 June',
'July 10/20/30',
'from June 1, july 5 to aug 5 please',
'2nd March to the 3rd January',
'15 march, 10 feb, 5 jan',
'1 nov 2017',
'27th Oct 2010 until 1st jan',
'27th Oct 2010 until 1st jan 2012'
]
cur_year = 2017
month_list = [m.lower() for m in list(calendar.month_name) + list(calendar.month_abbr) if len(m)]
remove_punc = string.maketrans(string.punctuation, ' ' * len(string.punctuation))
for date in tests:
date_parts = [get_date_part(part) for part in date.translate(remove_punc).split() if get_date_part(part)]
days = []
months = []
years = []
for k, g in groupby(sorted(date_parts, key=lambda x: x.isdigit()), lambda y: not y.isdigit()):
values = list(g)
if k:
months = map(month_full, values)
else:
for v in values:
if 1900 <= int(v) <= 2100:
years.append(int(v))
else:
days.append(v)
if days and months:
if years:
dates_raw = [datetime.strptime('{} {} {}'.format(m, d, y), '%b %d %Y') for m, d, y in izip_longest(months, days, years, fillvalue=years[0])]
else:
dates_raw = [datetime.strptime('{} {}'.format(m, d), '%b %d').replace(year=cur_year) for m, d in izip_longest(months, days, fillvalue=months[0])]
years = [cur_year]
# Fix for jumps in year
dates = []
start_date = datetime(years[0], 1, 1)
next_year = years[0] + 1
for d in dates_raw:
if d < start_date:
d = d.replace(year=next_year)
next_year += 1
start_date = d
dates.append(d)
print "{} -> {}".format(date, ', '.join(d.strftime("%d/%m/%Y") for d in dates))
这会按如下方式转换测试字符串:
I want to visit from May 16-May 18 -> 16/05/2017, 18/05/2017
I want to visit from May 16-18 -> 16/05/2017, 18/05/2017
I want to visit from May 6 May 18 -> 06/05/2017, 18/05/2017
May 6,7,8,9,10 -> 06/05/2017, 07/05/2017, 08/05/2017, 09/05/2017, 10/05/2017
8 May to 10 June -> 08/05/2017, 10/06/2017
July 10/20/30 -> 10/07/2017, 20/07/2017, 30/07/2017
from June 1, july 5 to aug 5 please -> 01/06/2017, 05/07/2017, 05/08/2017
2nd March to the 3rd January -> 02/03/2017, 03/01/2018
15 march, 10 feb, 5 jan -> 15/03/2017, 10/02/2018, 05/01/2019
1 nov 2017 -> 01/11/2017
27th Oct 2010 until 1st jan -> 27/10/2010, 01/01/2011
27th Oct 2010 until 1st jan 2012 -> 27/10/2010, 01/01/2012
其工作原理如下:
首先创建有效月份名称列表,即完整名称和缩写名称。
制作一个翻译表,以便轻松快速地从文本中删除任何标点符号。
分割文本,并使用带有正则表达式的函数来识别日期或月份,仅提取日期部分。
根据该部分是否为数字对列表进行排序,这会将月份分组到前面,将数字分组到末尾。
获取每个列表的第一部分和最后一部分。将月份转换为完整形式,例如Aug
到 August
并将每个转换为 datetime
对象。
如果某个日期早于前一个日期,请添加一整年。
关于python - 在 Python 中使用 Dateutil 时提取某些日期格式失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46220123/
我在玩dateutil module在 Python 2.7.3 中。我只是想使用: import dateutil dateutil.parser.parse("01-02-2013") 但我得到了
Java 文档中不清楚 DateUtils.ceiling 之间的区别是什么和 DateUtils.truncate是。 java文档错了吗?有人可以澄清一下吗? ceiling public sta
尝试使用 dateutil 解析未知格式的日期,但没有找到任何记录的方法? 代码: import dateutil print(dateutil.parser.parse("24.05.2017"))
我是 Python 新手。有人可以建议我如何处理错误 "ImportError: matplotlib requires dateutil"。我已经经历了类似的问题,但我已经按照那里提到的步骤下载了文
我在使用 python dateutil.zoneinfo 模块时遇到问题。注意: 损坏的 Ubuntu 机器是 ( Ubuntu 11.04 ) 工作的 Ubuntu 机器是 ( Ubuntu 11
我在这里遗漏了一些显然很简单的东西,但我不能说什么:我需要你的新眼光来告诉我:) $ pip install python-dateutil Requirement already satisfied
我试图在调用DateUtil.addDays的天数中使用一个变量,但是它不起作用。我是否缺少一些简单的东西,或者只是行不通? //Example: x = 10 //this int is the
如果我有以下字符串列表: a = ['Loc_RaffertytoLong_2004_02_21', 'Loc_RaffertytoLong_2004_02_22', 'Loc_Raffertyt
我正在尝试使用 apache-commons3 中的 DateUtils,但无法理解它所依赖的时区: Date date = DateUtils.truncate(date, Calendar.DAT
我正在使用 java DateUtils类 public boolean checkDate(String dateInString, String format){ try {
我在下面的示例代码中收到以下错误。我不确定导致错误的原因或原因,因为此代码过去运行良好。我正在使用 Python 2.7 AttributeError: 'module' object has no
r = [['21-09-1995', 3], ['22-11-1995', 2] , ['07-01-1988', 6], ['test', 4], ['12-12-2001', 5]] 有谁知道如
我使用 dateutil 解析日期得到以下堆栈跟踪: >>> dateutil.parser.parse('Sept 18 2014', fuzzy=True).date() Traceback (m
Python dateutil 正确解析字符串,但字符串的秒部分除外。 In [1]: from dateutil import parser In [2]: parser.parse("05/09/
我正在尝试解析从电子邮件标题中获取的以下日期字符串: from dateutil import parser d1 = parser.parse('Tue, 28 Jun 2011 01:46:52
我正在尝试将字符串类型的参数转换为日期时间。我正在使用 dateUtil 库 from dateutil import parser myDate_string="2001/9/1 12:00:0
我试图在执行 preparedStatement 之前更改服务器的时间。服务器时间是 EDT,我想在 preparedStatement 中使用它之前添加 6 个小时。 目前我收到这个错误: Date
我正在尝试查看日期列表是否为有效日期。我正在使用 dateutil 库,但我得到了奇怪的结果。例如,当我尝试以下操作时: import dateutil.parser as parser x = '1
有谁知道为什么 python 的 dateutil 在解析 datetime 字段时会反转 GMT 偏移量的符号? 显然这个特征是 known outcome不仅是 dateutil,还有其他解析函数
我正在使用 sixohsix 库从 Twitter API 解析一些推文数据。我正在尝试将推文的日期转换为我的语言环境: from pytz import timezone from dateutil
我是一名优秀的程序员,十分优秀!