2016-01-03 76 views
0

我知道這裏有很多關於「正則表達式python變量」的問題,但似乎沒有一個適合我。我一直在尋找兩個小時,但我沒有找到任何具體的問題的答案。正則表達式python變量

這是我的問題:我想搜索[ERROR][WARNING]的文字。正如你可能知道/var/log/mysql/error.log有一個標準的文件,基本上這樣year-month-day hour:minute

例子:

2016-01-03 13:19:40 1242 [Warning] Buffered warning: Changed limits: table_open_cache: 431 (requested 2000) 

2016-01-03 13:19:40 1242 [Warning] Using unique option prefix myisam-recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead. 
2016-01-03 13:19:40 1242 [Note] Plugin 'FEDERATED' is disabled. 

我有這個腳本在它試圖做的工作:

#!/usr/bin/python 

import re 
import time 
import datetime 
from datetime import datetime 

i = datetime.now() 
dia = i.day 
mes_abreviado = i.strftime('%b') 
hora = i.strftime('%H') 
minuto = i.strftime('%M') 
ano = i.strftime('%Y') 
mes_ano_num = i.strftime('%m') 
dia_00 = i.strftime('%d') 

#Data/Hora especifica "syslog" 
date = '%s %d %s:%s'% (mes_abreviado, dia, hora, minuto) 

#Data/Hora especifica do ficheiro "error.log" 
mysql_time = '%s-%s-%s %s:%s'% (ano, mes_ano_num, dia_00, hora, minuto) 

print mysql_time 
words = '\b\[ERROR\]\b|\b\[WARNING\]\b' 
print words 
file = open("/var/log/mysql/error.log", "rb") 

for line in file: 
     if re.findall(r'{0}'.format(words), line): 
#  if re.findall(r'{0}'.format(mysql_time), line): 
#    print "aqui" 
       print line 
file.close() 

我要得到當前的年,月,日,小時和分鐘搜索它在re.findall的功能。問題是:我需要將它們放在一個變量中,並在正則表達式中使用它們,但它似乎不起作用。

下面是輸出:

2016-01-03 14:21 
\[ERROR\\[WARNING\] 

正如你可以看到words不打印\b並且它搞亂了正則表達式。 我嘗試過使用words = re.compile(words)words = re.compile(r'\b\[ERROR\]\b|\b\[WARNING\]\b')re.findall(r'{0}'.format(words)。從看起來像正則表達式是非常好的。

代碼中有很多評論是我將解決後者的問題。如果有什麼缺失讓我知道,所以我可以編輯這個答案。先謝謝你。

+1

目前還不是很清楚您給出示例文件的實際輸出/結果。你能否詳細說明一下? – timgeb

+0

我沒有讀你的整個代碼,而是猜測:嘗試將'words ='\ b \ [ERROR \] \ b | \ b \ [WARNING \] \ b''改爲'words = r'\ b \正如@凱文所說 - 使用一個原始字符串文字 - '\ b's目前將被轉義爲退格字符,並且不會被存在。[錯誤\] \ b | \ b \ [警告\] \ b'' – Kevin

+0

考慮到正則表達式字邊界轉義字符 –

回答

1

我不知道你爲什麼在你的正則表達式中使用\ b - 當你正在查找的單詞已經被[和]分隔時,它沒有任何意義。根據文檔\ b匹配a-zA-Z_邊緣的零長度字符串,因此您的模式可以匹配'a [警告] b'。另外,在正則表達式中,我無法使[WARNING]與日誌文件中的[Warning]匹配(就像您提供的樣本數據一樣),但卻無法通過向其添加(?i)來確保正則表達式中的不區分大小寫。

將正則表達式更改爲:words = r'(?i)\[ERROR\]|\[WARNING\]'它應該開始工作。

一旦你的錯誤/警告匹配工作,你可以很容易地添加日期字符串匹配到你的正則表達式。

+0

謝謝。有效。昨天我讀了正則表達式文檔,我完全誤會了'\ b'字符。謝謝你糾正我。 –

1

你並不需要一個正則表達式來做到這一點,你只需要知道什麼是該領域的要檢查(第四場在您的示例)位置:

lookfor = ('[Warning]', '[Error]') 

with open('/var/log/mysql/error.log') as fh: 
    for line in fh: 
     parts = line.split(None, 5) 
     if len(parts) > 3 and parts[3] in lookfor: 
      print(line.rstrip()) 

關於你的代碼:

空格和方括號之間沒有詞邊界,因爲這兩個字符在相同的字符類\W中。 (字的邊界是一個字字符(\w)和非單詞字符(\W)或字符串的範圍之間。)

你並不需要使用re.findall當你在搜索字符串只出現一次。 re.search更適合此任務。

+0

非常感謝您的反饋,但是我想在發送「警告」或「錯誤」命令時將每個「警告」都發送至電子郵件。我認爲'findall'更適合這個。雖然你有一個很好的觀點。我可能會更改一些代碼來合併您的答案。 –

+0

@JoaoTorres:不,findall是沒用的,因爲你一行一行地工作(並且逐行工作是要走的路)。 –