2015-11-18 4 views
2

Я хотел бы извлечь регистрационную информацию из файла auth.log Linux и сообщить об этом, но у меня возникли проблемы с регулярным выражением, чтобы извлечь соответствующую информацию. Я думал, что группа, ограниченная пробелами (.*), будет соответствовать полному сегменту текста между этими пробелами. Он отлично подходит для первого слова и имени пользователя, но для IP-адреса он выплескивает всю строку текста, начиная с IP-адреса. Что мне не хватает?Почему мое регулярное выражение Python не совпадает между пробелами?

s='Accepted keyboard-interactive/pam for user101 from 10.19.36.76 port 36272 ssh2' 
s2='Postponed keyboard-interactive for user101 from 10.19.36.76 port 36303 ssh2 [preauth]' 

w = re.compile ("(.*) keyboard-interactive.*for (.*) from (.*) "); 
m = w.search(s2) 
if m: 
    print "login by:", m.group(2) 
    print "src ip :", m.group(3) 
    print "status :", m.group(1) 

ВЫВОД:

login by: user101 
src ip : 10.19.36.76 port 36303 ssh2 [preauth] 
status : Postponed 

ИЛИ:

login by: user101 
src ip : 10.19.36.76 port 36272 ssh2 
status : Accepted 
+1

"(. *)" Захватывает также пространство, возможно, вы имели в виду ([^] *)? или, поскольку это должно быть ip "([0-9] {1,3} \. [0-9] {1,3} \. [0-9] {1,3} \. [0- 9] {1,3}) "? – lejlot

ответ

1
w = re.compile ("(.*?) keyboard-interactive.*for (.*?) from (.*?) "); 

        ^^        ^^   ^^  

Сделайте регулярное выражение не жадный

1

Поскольку (.*) будет соответствовать каждой вещи (кроме новой строки) после from. Если вы просто хотите, чтобы соответствовать IP-адрес, который вы можете использовать класс символов, как следующее:

[\d.]+ 

Или и гораздо более безопасное использование подхода следующим:

((?:\d{1,3}\.){3}\d{1,3}) 
+1

или заменив все '(. *)' На '(\ S +)', выполнит эту работу отлично. –

+0

@AvinashRaj Yep, У него есть несколько способов, но я думаю, что более безопасный лучше. – Kasramvd

Смежные вопросы