0

我的日期格式如下:

   "1###-##-##" here # denote uncertainty. e.g.

   "1###-##-##" denotes (1000-00-00 to 1999-12-31)
   "-138 - ## - ##" denotes (0138-01-01 BC, 0138-12-31 BC) 
   "18##-##-##" denotes (1800-01-01, 1899-12-31)
   "1713-##-##" denotes (1713-01-01, 1713-12-31)
   "####-##-##" denotes (0001-01-01, 9999-12-31)

我试图通过使用没有效率的特定开关案例来实现这种转换。python中是否有其他方法可以实现这一点?

下面的零值被转换为 BC

编辑:我想要的输出给出了一个像“1###-##-##”这样的模式,找出最小和最大范围

4

2 回答 2

4

给定

dateranges = [
    "1***-**-**", 
    "-138 - ## - ##",
    "18##-##-##",
    "1713-##-##",
    "####-##-##"
]

re假设您不想正确执行此操作,您最好的解析器可能是:

import re
matcher = re.compile("(-?[\d*#]+)\s*-\s*([\d*#][\d*#])\s*-\s*([\d*#][\d*#])")

datetuples = [matcher.match(daterange).groups() for daterange in dateranges]

然后你可以通过元组,

for year, month, day in datetuples:

将每个未知数转换为数字和上限。

    minyear  = int(year.replace("*", "0").replace("#", "0"))
    minmonth = max(1, int(month.replace("*", "0").replace("#", "0")))
    minday   = max(1, int(day.replace("*", "0").replace("#", "0")))

    mindate = (minyear, minmonth, minday)

    maxyear  = int(year.replace("*", "9").replace("#", "9"))
    maxmonth = min(12, int(month.replace("*", "9").replace("#", "9")))
    ### WARNING! MAXIMUM DAY NUMBER DEPENDS ON BOTH MONTH AND YEAR
    maxday  = min(31, int(day.replace("*", "9").replace("#", "9")))

    maxdate = (maxyear, maxmonth, maxday)

    print(mindate, maxdate)

#>>> (1000, 1, 1) (1999, 12, 31)
#>>> (-138, 1, 1) (-138, 12, 31)
#>>> (1800, 1, 1) (1899, 12, 31)
#>>> (1713, 1, 1) (1713, 12, 31)
#>>> (0, 1, 1) (9999, 12, 31)

请记住,由于上限,这会接受误报,并且还要记住大而大胆的警告。

于 2013-09-25T23:17:23.503 回答
0

如果我理解正确,您希望 * 表示从 0 到最大值的范围,而 # 表示从 1 到最大值的范围。此外,以破折号开头的日期在 BC。

这比你原来的方法更好吗?

def getdaterange(inputdate):
    inputdate = inputdate.replace(' ', '')

    maxdate = '9999-12-31'
    zerodate = '0000-00-00'
    onedate = '0001-01-01'

    lowdate = list(inputdate)
    highdate = list(inputdate)

    for i, ch in enumerate(inputdate):
        if ch == '*' or ch == '#':
            highdate[i] = maxdate[i]

        if ch == '*':
            lowdate[i] = zerodate[i]
        elif ch == '#':
            lowdate[i] = onedate[i]

    if inputdate[0] == '-':
        lowdate[0], highdate[0] = '0', '0'
        lowdate.append(' BC')
        highdate.append(' BC')

    return (''.join(lowdate), ''.join(highdate))

testins = ('1***-**-**', '-138 - ## - ##', '18##-##-##',
            '1713-##-##', '####-##-##')
for i in testins:
    print(getdaterange(i))

输出看起来正确。

('1000-00-00', '1999-12-31')
('0138-01-01 BC', '0138-12-31 BC')
('1801-01-01', '1899-12-31')
('1713-01-01', '1713-12-31')
('0001-01-01', '9999-12-31')

当然,它不会验证函数的输入。可能值得在开头添加一些正则表达式以验证输入的格式是否正确。

于 2013-09-26T00:18:17.980 回答