【问题标题】:Using python regex to create a JSON array of temperature data使用 python 正则表达式创建温度数据的 JSON 数组
【发布时间】:2013-10-06 21:16:51
【问题描述】:

我有一个以下列格式存储温度的日志文件:

2013/09/30 11:23:01 Temperature 41.34F 5.19C
2013/09/30 11:23:01 Temperature 99.84F 37.69C
2013/09/30 11:23:01 Temperature 65.86F 18.81C
2013/09/30 11:25:02 Temperature 41.67F 5.38C
2013/09/30 11:25:02 Temperature 65.64F 18.69C
2013/09/30 11:25:02 Temperature 98.83F 37.12C

对应于给定分钟的值的数量是可变的,从 1 到 3。如何使用 Python 正则表达式将数据转换为 JSON 格式,从而为每次给出一系列值和华氏值?

{"c":[{"v":"Date(2013, 8, 30, 11, 23)"},{"v":41.34},{"v":99.84},{"v":65.86}]},

因此脚本将打开“temperatures.log”,通读文件,获取时间值并将其格式设置为:

{"c":[{"v":"Date(2013, 8, 30, 11, 23)"}, 

(月份偏移-1)

然后循环遍历当时的所有温度值并包括每个喜欢:

{"v":41.34},

直到找到与上一行不同的日期/时间表达式,然后用

关闭表达式
]}, 

写入输出文件,然后开始下一个系列,直到日志文件结束。

【问题讨论】:

  • 这几乎是陈词滥调,但仍然是:“当遇到问题时,程序员会想,'啊哈!我将使用正则表达式!'现在他有两个问题。” - 正则表达式是一个完全有效的工具,但它有一个非常特殊的位置。就像您在工具箱后面的一个专业工具一样,除了它的一个预期目的之外,它对任何事情都毫无用处。

标签: python regex json


【解决方案1】:

您不需要正则表达式,因为您的数据非常简单。首先,请注意,您甚至可以在不解析日期的情况下组织数据,因为您可以使用简单的字符串比较:

def proc_lines(lines):
    cur_date = None
    cur_temps = []

    results = []

    for line in lines:
        parts = line.split()
        date = "%s %s" % (parts[0], parts[1])
        if date != cur_date:
            if cur_temps:
                #save current data
                results.append((cur_date, cur_temps))
            #reset state
            cur_date = date
            cur_temps = []
        #add the line's temperature in fahrenheit, stripping out the 'F'
        cur_temps.append(float(parts[3][:-1]))

    #process the last line
    if cur_temps:
        results.append((cur_date, cur_temps))

    return results

现在results 将成为(date, temperature) 元组的列表,其中包含未解析的日期:

>>> lines = """2013/09/30 11:23:01 Temperature 41.34F 5.19C
2013/09/30 11:23:01 Temperature 99.84F 37.69C
2013/09/30 11:23:01 Temperature 65.86F 18.81C
2013/09/30 11:25:02 Temperature 41.67F 5.38C
2013/09/30 11:25:02 Temperature 65.64F 18.69C
2013/09/30 11:25:02 Temperature 98.83F 37.12C""".split("\n")
>>> results = proc_lines(lines)
>>> results
[('2013/09/30 11:23:01', [41.340000000000003, 99.840000000000003, 
                          65.859999999999999]), 
 ('2013/09/30 11:25:02', [41.670000000000002, 65.640000000000001, 
                          98.829999999999998])]

您可以使用datetime.datetime.strptime 实际解析日期并处理日期(根据您的要求减去月份):

>>> import datetime
>>> def proc_datestr(date):
        dt = datetime.datetime.strptime(date, "%Y/%m/%d %H:%M:%S")
    return "Date(%d, %d, %d, %d, %d, %d)" % (
        dt.year, dt.month - 1, dt.day, dt.hour, dt.minute, dt.second)

>>> proc_datestr(results[0][0])
'Date(2013, 8, 30, 11, 23, 1)'

注意格式字符串"%Y/%m/%d %H:%M:%S",它解析日期as detailed here。这个可爱的内置函数让您无需编写自己的正则表达式来处理日期。

然后您只需按如下方式处理结果并转储到 json:

>>> import json
>>> def proc_result(result):
    date, temps = result
    res = {'c': [{'v': proc_datestr(date)}]}
    for temp in temps:
        res['c'].append({'v': temp})
    return json.dumps(res)

>>> proc_result(results[0])
'{"c": [{"v": "Date(2013, 8, 30, 11, 23, 1)"}, {"v": 41.340000000000003}, {"v": 99.840000000000003}, {"v": 65.859999999999999}]}'
>>> proc_result(results[1])
'{"c": [{"v": "Date(2013, 8, 30, 11, 25, 2)"}, {"v": 41.670000000000002}, {"v": 65.640000000000001}, {"v": 98.829999999999998}]}'

【讨论】:

    猜你喜欢
    • 2014-05-08
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 2012-10-04
    相关资源
    最近更新 更多