在字符串中查找和格式化非正式日期的正确方法是什么?
What would be the correct approach to find and format an informally written date in a string?
我有一个小项目,我在 firebase 数据库中将日期非正式地写为字符串。我需要将这些日期转换为日期时间格式。这是假设日期有效。网站中的输入不能修改(这是解决这个问题的全部前提)。还假设月份是按名称书写的,月份采用 YYYY 格式。
我对这些条目的一些示例进行了分类:
几乎露骨:
"13 july 2017", "3 december 2008", "december 2016", "21 december 2017", "2020", "24 november 2017", "14 march 2012", "22 july 2016", "20 february 2012", "17 january 2011", "obtained july 2013"...
这些会比较容易。年份始终是 4 位数字,日期是 2 位数字,月份是字符串。这些可以是 checked/compared,如果他们错过了确切的日期(1 或 2 位数字),我可以假设它可以作为第一个(一个月中的某天),同样适用于没有指定的月份(假设 1 月。 )
其他简单字符串:
"When the group is ready", "Not specified", "Canceled", "set."
这些不包含日期,因此不重要。只需检查没有数字就可以完成工作。这些可以设置为00-00-0000,没关系。
较难的:
"Within 12 or 24 months", "Q4 2013", "Late autumn 2019"
我在想:
如果我读 "within",我会计算当前日期,加上它后面的数字(天、月、年)。
如果我将Q(quarters)定义为一张地图
Q={1:(1,2,3), 2:(4,5,6), 3:(7,8,9), 4:(10,11,12)}
和单词
when = {"Early" : 1, "Mid": 2, "Late": 3}
季节也一样。
例如,我可以访问第四季度 Q 的第 4 个元素并获取它的月份,或者晚 spring 作为季节 ["spring"] 并获取 [=67= 的月份].
回到问题:
我不确定我是否应该使用正则表达式、映射和如此多的比较来解决这个问题,会引入很多错误,或者使用某种 AI,但我还不太精通这门学科。
所以,回到问题,你会如何处理这类问题?
是否有任何图书馆可以提供帮助?
我觉得这里没有一个非常简单的实现,或者我知道的方法效率低下并且需要大量硬编码。
这是我所做的。如果有人需要解决这样的问题。
此代码可以优化,但我没有时间 atm。
假设:日期的格式为 [anything] DD [anything] month (written) [anything] YYYY
假设:如果未指定日期,则首选数字 1。几个月都一样。
import re
def validate_date(d,m,y):
leap = False
valid = False
y = int(y)
d = int(d)
m = int(m)
if(y % 400 == 0):
leap=True
if(y % 100 == 0):
leap = False
if(y % 4 == 0):
leap = True
if (m<13):
if (m == 1 | m==3 | m== 5 | m==7 | m==8 | m==10 | m==12 ):
if (d <=31):
valid=True
if (m == 4 | m==6 | m==9 | m==11 ):
if (d <= 30):
valid = True
if (m==2):
if (leap == True):
if (d <= 29):
valid = True
if (leap == False):
if (d <= 28):
valid = True
return valid
months = {
1: "januari",
2: "februari",
3: "mars",
4: "april",
5: "maj",
6: "juni",
7: "juli",
8: "augusti",
9: "september",
10: "oktober",
11: "november",
12: "december"
}
def validate(date):
month=0
day=0
year=0
raw_date = str(date)
#get the integers in the text
raw_date = raw_date.lower()
if (not ("q1" in raw_date or "q2" in raw_date or
"q3" in raw_date or "q4" in raw_date)):
if (len(re.findall('\d+', raw_date))==2):
day, year = map(int, re.findall('\d+', raw_date))
elif (len(re.findall('\d+', raw_date))==3):
day, month, year = re.findall('\d+', raw_date)
else:
if (len(re.findall('\d+', raw_date))==2):
quarter, year = map(int, re.findall('\d+', raw_date))
day = 1
#Set month to the string found, if any.
if (month==0):
if (months.get(1) in raw_date or ("q1" in raw_date)): month = 1
elif(months.get(2) in raw_date): month = 2
elif(months.get(3) in raw_date): month = 3
elif(months.get(4) in raw_date or ("q2" in raw_date)): month = 4
elif(months.get(5) in raw_date): month = 5
elif(months.get(6) in raw_date): month = 6
elif(months.get(7) in raw_date or ("q3" in raw_date)): month = 7
elif(months.get(8) in raw_date): month = 8
elif(months.get(9) in raw_date): month = 9
elif(months.get(10) in raw_date or ("q4" in raw_date)): month = 10
elif(months.get(11) in raw_date): month = 11
elif(months.get(12) in raw_date): month = 12
else: month = 1
clean_date = str(str(day)+"-"+str(month)+"-"+str(year))
# print (clean_date)
if (validate_date(day,month,year)==False): return "00-00-0000"
else: return str(clean_date)
我有一个小项目,我在 firebase 数据库中将日期非正式地写为字符串。我需要将这些日期转换为日期时间格式。这是假设日期有效。网站中的输入不能修改(这是解决这个问题的全部前提)。还假设月份是按名称书写的,月份采用 YYYY 格式。
我对这些条目的一些示例进行了分类:
几乎露骨:
"13 july 2017", "3 december 2008", "december 2016", "21 december 2017", "2020", "24 november 2017", "14 march 2012", "22 july 2016", "20 february 2012", "17 january 2011", "obtained july 2013"...
这些会比较容易。年份始终是 4 位数字,日期是 2 位数字,月份是字符串。这些可以是 checked/compared,如果他们错过了确切的日期(1 或 2 位数字),我可以假设它可以作为第一个(一个月中的某天),同样适用于没有指定的月份(假设 1 月。 )
其他简单字符串:
"When the group is ready", "Not specified", "Canceled", "set."
这些不包含日期,因此不重要。只需检查没有数字就可以完成工作。这些可以设置为00-00-0000,没关系。
较难的:
"Within 12 or 24 months", "Q4 2013", "Late autumn 2019"
我在想:
如果我读 "within",我会计算当前日期,加上它后面的数字(天、月、年)。
如果我将Q(quarters)定义为一张地图
Q={1:(1,2,3), 2:(4,5,6), 3:(7,8,9), 4:(10,11,12)}
和单词
when = {"Early" : 1, "Mid": 2, "Late": 3}
季节也一样。
例如,我可以访问第四季度 Q 的第 4 个元素并获取它的月份,或者晚 spring 作为季节 ["spring"] 并获取 [=67= 的月份].
回到问题:
我不确定我是否应该使用正则表达式、映射和如此多的比较来解决这个问题,会引入很多错误,或者使用某种 AI,但我还不太精通这门学科。
所以,回到问题,你会如何处理这类问题?
是否有任何图书馆可以提供帮助?
我觉得这里没有一个非常简单的实现,或者我知道的方法效率低下并且需要大量硬编码。
这是我所做的。如果有人需要解决这样的问题。
此代码可以优化,但我没有时间 atm。
假设:日期的格式为 [anything] DD [anything] month (written) [anything] YYYY
假设:如果未指定日期,则首选数字 1。几个月都一样。
import re
def validate_date(d,m,y):
leap = False
valid = False
y = int(y)
d = int(d)
m = int(m)
if(y % 400 == 0):
leap=True
if(y % 100 == 0):
leap = False
if(y % 4 == 0):
leap = True
if (m<13):
if (m == 1 | m==3 | m== 5 | m==7 | m==8 | m==10 | m==12 ):
if (d <=31):
valid=True
if (m == 4 | m==6 | m==9 | m==11 ):
if (d <= 30):
valid = True
if (m==2):
if (leap == True):
if (d <= 29):
valid = True
if (leap == False):
if (d <= 28):
valid = True
return valid
months = {
1: "januari",
2: "februari",
3: "mars",
4: "april",
5: "maj",
6: "juni",
7: "juli",
8: "augusti",
9: "september",
10: "oktober",
11: "november",
12: "december"
}
def validate(date):
month=0
day=0
year=0
raw_date = str(date)
#get the integers in the text
raw_date = raw_date.lower()
if (not ("q1" in raw_date or "q2" in raw_date or
"q3" in raw_date or "q4" in raw_date)):
if (len(re.findall('\d+', raw_date))==2):
day, year = map(int, re.findall('\d+', raw_date))
elif (len(re.findall('\d+', raw_date))==3):
day, month, year = re.findall('\d+', raw_date)
else:
if (len(re.findall('\d+', raw_date))==2):
quarter, year = map(int, re.findall('\d+', raw_date))
day = 1
#Set month to the string found, if any.
if (month==0):
if (months.get(1) in raw_date or ("q1" in raw_date)): month = 1
elif(months.get(2) in raw_date): month = 2
elif(months.get(3) in raw_date): month = 3
elif(months.get(4) in raw_date or ("q2" in raw_date)): month = 4
elif(months.get(5) in raw_date): month = 5
elif(months.get(6) in raw_date): month = 6
elif(months.get(7) in raw_date or ("q3" in raw_date)): month = 7
elif(months.get(8) in raw_date): month = 8
elif(months.get(9) in raw_date): month = 9
elif(months.get(10) in raw_date or ("q4" in raw_date)): month = 10
elif(months.get(11) in raw_date): month = 11
elif(months.get(12) in raw_date): month = 12
else: month = 1
clean_date = str(str(day)+"-"+str(month)+"-"+str(year))
# print (clean_date)
if (validate_date(day,month,year)==False): return "00-00-0000"
else: return str(clean_date)