2013-09-30 64 views
1

我具有存儲溫度的格式的日誌文件的JSON數組:使用Python正則表達式來創建溫度數據

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}, 

直到它發現,是從上一行不同的日期/時間表達,然後關閉該表達與

]}, 

寫入輸出文件,並開始下一次系列,直到日誌文件的末尾。

+1

這幾乎是老生常談,但仍然!「當面對一個問題,程序員會想,「啊哈,我將使用一個正則表達式!'而現在他有兩個問題。「 - 正則表達式是一個非常有效的工具,但它有一個非常特殊的地方。就像你在工具箱背後擁有的一種專業工具,除了它的一個預期目的外根本就沒有任何用處。 –

回答

3

你不需要正則表達式,因爲你的數據非常簡單。首先,請注意,您可以組織數據,甚至沒有解析日期,因爲你可以用簡單的字符串比較:

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}]}'