#python #regex #verbose
Вопрос:
Я пытаюсь получить словарь различных ключей следующим образом. проблема в том, что этот код пропускает 2 — ю строку, в которой есть имя пользователя другого типа .т. е. имя пользователя = — также в последней строке, которую я вижу, изначально есть место перед хостом.не могли бы вы помочь разобраться в проблеме?
import re
def logs():
logdata = """146.204.224.152 - feest6811 [21/Jun/2019:15:45:24 -0700] "POST /incentivize HTTP/1.1" 302 4622
159.253.153.40 - - [21/Jun/2019:15:46:10 -0700] "POST /e-business HTTP/1.0" 504 19845
197.109.77.178 - kertzmann3129 [21/Jun/2019:15:45:25 -0700] "DELETE /virtual/solutions/target/web services HTTP/2.0" 203 26554"""
# YOUR CODE HERE
pattern="""
(?P<host>.*)
( - )
(?P<user_name>w.*)
( [)
(?P<time>.*)
(] ")
(?P<request>w.*)
(")
"""
for item in re.finditer(pattern,logdata,re.VERBOSE):
print(item.groupdict())
return
Ответ №1:
Вы ищете только имена пользователей, состоящие из слов, но » — » — это не слово.
Если вы измените регулярное выражение на:
pattern="""
(?P<host>.*)
( - )
(?P<user_name>(w.*|-))
( [)
(?P<time>.*)
(] ")
(?P<request>w.*)
(")
"""
Вы будете искать либо слова, либо» -»
Ответ №2:
Вы можете сделать шаблон немного более конкретным, не используя .*
, который сначала будет совпадать до конца строки, а затем может вернуться, чтобы соответствовать следующим частям шаблона, чтобы получить общее совпадение.
Поскольку формат журналов кажется одинаковым, вы можете сопоставить хост и имя пользователя, соответствующие 1 символам без пробелов, используя S
, как представляется, пробелы отсутствуют.
Конечно, вы также можете сделать детали более конкретными, чтобы они соответствовали ip-номеру хоста и времени, подобному шаблону для времени.
(?P<host>S ) - (?P<user_name>S ) [(?P<time>[^][]*)] "(?P<request>w[^"]*)"
По частям шаблон совпадает:
(?P<host>S )
Группаhost
, совпадение 1 символов без пробелов-
Совпадение буквально(?P<user_name>S )
Группаuser_name
соответствует 1 символам без пробелов и пробелу[(?P<time>[^][]*)]
Групповоеtime
соответствие все в квадратных скобках"(?P<request>w[^"]*)"
Групповоеrequest
совпадение всех между двойными кавычками
Демонстрация регулярных выражений
Например, без re.VERBOSE
флага
import re
def logs():
logdata = """146.204.224.152 - feest6811 [21/Jun/2019:15:45:24 -0700] "POST /incentivize HTTP/1.1" 302 4622
159.253.153.40 - - [21/Jun/2019:15:46:10 -0700] "POST /e-business HTTP/1.0" 504 19845
197.109.77.178 - kertzmann3129 [21/Jun/2019:15:45:25 -0700] "DELETE /virtual/solutions/target/web services HTTP/2.0" 203 26554"""
pattern = '(?P<host>S ) - (?P<user_name>S ) [(?P<time>[^][]*)] "(?P<request>w[^"]*)"'
for item in re.finditer(pattern, logdata):
print(item.groupdict())
logs()
Выход
{'host': '146.204.224.152', 'user_name': 'feest6811', 'time': '21/Jun/2019:15:45:24 -0700', 'request': 'POST /incentivize HTTP/1.1'}
{'host': '159.253.153.40', 'user_name': '-', 'time': '21/Jun/2019:15:46:10 -0700', 'request': 'POST /e-business HTTP/1.0'}
{'host': '197.109.77.178', 'user_name': 'kertzmann3129', 'time': '21/Jun/2019:15:45:25 -0700', 'request': 'DELETE /virtual/solutions/target/web services HTTP/2.0'}