Как я могу разделить эту строку (строку журнала) по нескольким различным символам / шаблонам? - PullRequest
1 голос
/ 31 октября 2019

У меня есть такая строка:

66.249.69.97 - - [24/Sep/2014:22:25:44 +0000] "GET /071300/242153 HTTP/1.1" 404 514 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

У меня огромная проблема при разборе этой вещи. Мне просто нужен IP-адрес, дата, метод «GET», код ответа (404, в этой строке) и остальная часть в виде более длинной строки. Результатом должен быть список, разделенный запятыми, например:

['66.249.69.97', '24/Sep/2014:22:25:44 +0000', '"GET /071300/242153 HTTP/1.1"','404','"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"']

Это нормально, если решение не возвращает именно это, но я часами пытался разобрать это и понятия не имею, как это сделать.

Я пробовал split() и strip() в циклах и собираюсь попробовать регулярное выражение ... которое я должен был бы просмотреть / переучить. Есть ли более простые способы, которые я просто пропускаю?

Я использую ноутбук Python2, поэтому нет вариантов Python3.

Заранее спасибо!


Редактировать: @Теперь у меня есть это:

    p = re.compile(r'(?P<ip_addr>\d+(\.\d+){3}) - - \[(?P<date_time>.+?)\] (?P<http_method>\".+?\") (?P<return_code>\d+) \d+ "-" (?P<client>\".+?\")')
    def pattern_match(line):
          m = p.search(line)
          return([m.group('ip_addr'), m.group('date_time'), m.group('http_method'), m.group('return_code'), m.group('client')])

Затем я использую эту функцию в:

    for line in rdd.collect():
        line = pattern_match(line)
        print(line)

rdd.collect() - это 5 строк текста, и когда я выполняю задание на печать через него, онопечатает все 5. Однако теперь я получаю только 4 напечатанных таким образом ... и затем выдает ошибку: AttributeError: 'NoneType' object has no attribute 'group'.

Есть идеи?

Ответы [ 2 ]

1 голос
/ 31 октября 2019

Вот один из способов сделать это:

>>> import re
>>> s = '''66.249.69.97 - - [24/Sep/2014:22:25:44 +0000] "GET /071300/242153 HTTP/1.1" 404 514 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"'''
>>> p = re.compile(r'(?P<ip_addr>\d+(\.\d+){3}) - - \[(?P<date_time>.+?)\] (?P<http_method>\".+?\") (?P<return_code>\d+) \d+ "-" (?P<client>\".+?\")')
>>> m = p.search(s)
>>> [m.group('ip_addr'), m.group('date_time'), m.group('http_method'), m.group('return_code'), m.group('client')]
['66.249.69.97', '24/Sep/2014:22:25:44 +0000', '"GET /071300/242153 HTTP/1.1"', '404', '"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"']

Обратите внимание, что регулярное выражение делает здесь некоторые предположения и может работать не во всех ваших случаях, но оно должно помочь вам начать.

(Это будет стоить вашего времени на изучение регулярных выражений . Надеюсь, это поможет вам начать: -).)

0 голосов
/ 31 октября 2019

Предполагается, что Regex - это путь, но есть и другие вещи, которые вы можете попробовать сделать в качестве альтернативы, например:

temp1 = '66.249.69.97 - - [24/Sep/2014:22:25:44 +0000] "GET /071300/242153 HTTP/1.1" 404 514 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"'.split("\"")
temp2 = temp1[0].split("-")
print [temp2[0].strip(), temp2[-1].strip(" []")] + [i.strip() for i in temp1[1:] if i not in "- "]

Это не идеально и, возможно, немного некрасиво, ночестно говоря, мне это нравится больше, чем регулярным выражениям, потому что мне гораздо легче читать.

...