2017-01-09 34 views
1

我正在嘗試使用Python處理日誌文件,並提取每個條目的日期,時間和日誌消息並將其存儲在一個列表中。爲此,我正在使用re.search()group()方法。
問題是日期/時間採取各種格式,如。用Python中的正則表達式匹配多種可能性

dd/mm/yy, hh:mm AM - logs 
dd/mm/yyyy, hh:mm a.m. - logs 
dd/mm/yy HH:mm - logs 

我的計劃看起來是這樣的:

import re 
infile=open('logfile.txt', 'r') 
loglist=[] 
logdict={} 
for aline in infile.readlines(): 
    line=re.search(r'^(\d?\d/\d?\d/\d\d), (\d?\d:\d?\d \w\w) - (.*?)',aline) 
    if line: 
     logdict['date'] = line.group(1) 
     logdict['time'] = line.group(2) 
     logdict['logmsg'] = line.group(3) 
     loglist.append(logdict) 

然而,這僅僅匹配前的上述格式。
我怎樣才能匹配其他格式以及維護組?還是有更簡單的方法來做到這一點?

+1

是否有行*不匹配模式?一種選擇就是假設'datetime,message = line.split(' - ')'。 – jonrsharpe

回答

2

您可以在模式之後使用{m,n}來指示可能存在mn之間的重複。因此請使用\d{1,2}來表示1或2位數字。而且你使用一個交替表示多種可能性,例如爲2位或4位數年份的\d{2}|\d{4}

所以正則表達式可以是:

^(\d{1,2}/\d{1,2}/(?:\d{2}|\d{4})),? (\d{1,2}:\d{1,2}(?: [AaPp]\.?[Mm]\.?)?) - (.*)' 
+0

這工作完美。謝謝! – Shravan

-1

通過分割了「 - 」,然後由「」或‘’

0

我首先與正則表達式中提取數據,然後手動驗證它。我不會使用正則表達式來進行驗證和提取兩件事。

爲了清晰起見,我還會爲這些正則表達式分配名稱,並確保每個單獨的正則表達式都會返回一個原子,如時間或日期或am_pm,然後將它們串起來形成句子。 注意:我還沒有爲組分配名稱,但我認爲它是可能的但不知道如何,但是最終你可以得到你的date_time並在它上面做一個分割,比如date_time.split(「/」),其中會返回你日,月,年,然後你可以驗證或使用。

import re 

log_records = ["10/10/1960, 10:50 AM - logs", 
       "5/15/2001, 23:11 a.m. - logs", 
       "50/100/1069 300:100 - logs"] 
parsed_records = [] 

date_month_year_ptrn = r"((\d+/){2,2}\d+)" 
time_ptrn = r"(\d+:\d+)" 
morning_evening_ptrn = r"((\w+\.?)+)?" 
everything_else_ptrn = r"(.*)" 

log_record_ptrn = "^{date_ptrn},?\s+{time_ptrn}\s+{morn_even_ptrn}\s*-\s+{log_msg}$" 
log_record_ptrn = log_record_ptrn.format(date_ptrn=date_month_year_ptrn, 
             time_ptrn=time_ptrn, 
             morn_even_ptrn=morning_evening_ptrn, 
             log_msg=everything_else_ptrn) 

def extract_log_record_from_match(matcher): 
    if log_record_match: 
     # I am pretty sure you can attach names to these numbers 
     # but not sure how to do this 
     date_time = log_record_match.group(1) 
     time_ = log_record_match.group(3) 
     am_pm = log_record_match.group(4) 
     log_message = log_record_match.group(6) 
     return date_time, time_, am_pm, log_message 
    return None 

def print_records(records): 
    for record in parsed_records: 
     if record: 
      print(record) 


for log_record in log_records: 
    log_record_match = re.search(log_record_ptrn, log_record, re.IGNORECASE) 
    parsed_records.append(extract_log_record_from_match(log_record_match)) 

print_records(parsed_records)