2016-08-25 127 views
1

我想從下面的日誌消息中提取字段。從python中的字符串消息中提取括號'[]'中指定的數據

實施例:

忽略項,受影響的列[列1:列2],原因[某種原因],詳細說明[一些條目細節]

我需要提取在指定的數據括號[ ]爲「受影響的列,原因,詳細信息」

在Python中提取這些字段的有效方法是什麼?

注意:如果需要,我可以修改日誌消息格式。

+3

're。findall('\ [([^]] +),str)' – Maroun

回答

2

如果您可以自由更改日誌格式,那麼最簡單的方法就是使用常見的數據格式 - 我推薦使用JSON來處理這些數據。它是結構化的,但是足夠輕便,甚至可以從自定義bash腳本編寫它。該json module允許您直接將其轉換爲本地Python對象:

import json # python has a default parser 
# assume this is your log message 
log_line = '{"Ignoring entry" : {"Affected columns": [1, 3], "reason" : "some reason", "Details": {}}}' 
data = json.loads(log_line) 
print("Columns to ignore:", data["Ignoring entry"]["Affected columns"]) 

如果您想使用當前格式的工作,你必須與str方法或re模塊工作。

例如,你可以這樣做:

log_msg = "Ignoring entry, Affected columns [column1:column2], reason[some reason], Details[some entry details]" 
def parse_log_line(log_line): 
    if log_line.startswith("Ignoring entry"): 
    log_data = { 
    for element in log_line.split(',')[1:]: # parse all elements but the header 
     key, value = element.partition('[') 
     if value[-1] != ']': 
     raise ValueError('Malformed Content. Expected %r to end with "]"' % element) 
     value = value[:-1] 
     log_data[key] = value 
    return log_data 
    raise ValueError('Unrecognized log line type') 

許多解析任務是 最好 re module緊湊處理。它允許你使用正則表達式。他們非常強大,但如果你不習慣,很難保持。在你的情況,下面將工作:

log_data = {key: value for key, value in re.findall(',\s?(.+?)\s?\[(.+?)\]', log_line)} 

重新工作原理是這樣:

  • ,文字逗號分隔條目
  • \s*空白的逗號之後以任意順序,前下一個元素
  • (.+?)任何非空白字符(密鑰,通過'()'捕獲)
  • \s*空白的鍵和值之間的任意的序列
  • \[字面[
  • (.+?)的下一個元素(值,經由'()'捕獲)
  • \]文字之前的非空白字符的最短序列]

符號*+?表示 「任何」,「米礦石比一個「和」儘可能少「。

+0

爲什麼不簡單地're.findall('\ [([^]] +),str)'? – Maroun

+0

@MarounMaroun主要是因爲'str'方法更適合於編寫你自己的解析器是一個壞主意。 ;)其次,你不重要,並且缺少結束語。 re''(。+?)?\ [(。+?)\]'效果更好,但也不利於可讀性。 – MisterMiyagi

+0

謝謝MisterMiyagi,Maroun。它的工作正常:) –