python中的特定数据转换

时间:2013-09-25 22:50:58

标签: python python-2.7

我的日期格式如下:

   "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 ### - ## - ##”的模式,找出最小和最大范围

2 个答案:

答案 0 :(得分: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)

请记住,这会因为上限而接受误报,并牢记大胆的警告。

答案 1 :(得分: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')

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