Python3 - регулярная компиляция для traceroute - PullRequest
0 голосов
/ 09 января 2019

Я пытаюсь создать скрипт Python, который будет фильтровать и выбирать соответствующие IP-адреса из входных данных traceroute ...

Это ввод:

Hostname#traceroute 10.0.0.1

Type escape sequence to abort.
Tracing the route to 10.0.0.1

 1 10.0.0.2 0 msec 6 msec 0 msec
11 10.0.0.3 115 msec
   10.0.0.4 115 msec 116 msec

Я создаю список из этого:

hosts = ['Hostname#traceroute 10.0.0.1', 'Type escape sequence to abort.', 'Tracing the route to 10.0.0.1', ' 1 10.0.0.2 0 msec 6 msec 0 msec', '11 10.0.0.3 115 msec', '   10.0.0.4 115 msec 116 msec']

Теперь моя цель - отфильтровать элементы, которые мне не нужны, и оставить только последние 3 строки:

pattern = re.compile(r"(?<=\s\s\s|\s\d\s|\s\d\d)\d+\.\d+\.\d+\.\d+")
ip = list(filter(pattern.match, hosts))

Я протестировал само регулярное выражение в онлайн-генераторах, так что все должно быть в порядке, но в Python я получаю пустой список, который указывает на отсутствие соответствия.

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

    return _compile(pattern, flags).sub(repl, string, count)
TypeError: expected string or bytes-like object

1 Ответ

0 голосов
/ 09 января 2019

Здесь две маленькие вещи не так,

Во-первых, в вашем регулярном выражении, при поиске чередования, это |\s\d\d) неверно, так как строка "11", следовательно, ваше регулярное выражение должно быть |\d\d\s)

И вторая проблема в том, что вы используете match вместо findall . Match используется для соответствия всей строке, но ваше регулярное выражение не может соответствовать всей строке, поэтому использование findall в этом filter(pattern.findall, hosts) решает проблему.

Если вы хотите, чтобы ваш код работал с match вместо findall , попробуйте использовать это регулярное выражение .*\d+\.\d+\.\d+\.\d+\s.*, которое будет соответствовать только последним трем строкам и даст вам ожидаемый результат.

Запустите свой импровизированный код и посмотрите, как он печатает ожидаемый результат,

import re

s = '''Hostname#traceroute 10.0.0.1

Type escape sequence to abort.
Tracing the route to 10.0.0.1

 1 10.0.0.2 0 msec 6 msec 0 msec
11 10.0.0.3 115 msec
   10.0.0.4 115 msec 116 msec'''

hosts = re.findall(r'(.*)\n*',s)

pattern = re.compile(r"(?<=\s\s\s|\s\d\s|\d\d\s)\d+\.\d+\.\d+\.\d+")
ip = list(filter(pattern.findall, hosts))

print(ip)

Который печатает последние три строки, как вы ожидали,

[' 1 10.0.0.2 0 msec 6 msec 0 msec', '11 10.0.0.3 115 msec', '   10.0.0.4 115 msec 116 msec']

Кроме того, если вы просто хотите напечатать последние три строки, вы можете использовать тот факт, что в последних трех строках за IP следует пробел, и, следовательно, вы могли бы также использовать упрощенное регулярное выражение, подобное этому pattern = re.compile(r"\d+\.\d+\.\d+\.\d+\s"), которое также дал вам последние три строки.

Редактировать: коды для регулярных выражений с пробелом после IP

import re

s = '''Hostname#traceroute 10.0.0.1

Type escape sequence to abort.
Tracing the route to 10.0.0.1

 1 10.0.0.2 0 msec 6 msec 0 msec
11 10.0.0.3 115 msec
   10.0.0.4 115 msec 116 msec'''

hosts = re.findall(r'(.*)\n*',s)

pattern = re.compile(r"\d+\.\d+\.\d+\.\d+\s")
ip = list(filter(pattern.findall, hosts))

print(ip)

Какие отпечатки,

[' 1 10.0.0.2 0 msec 6 msec 0 msec', '11 10.0.0.3 115 msec', '   10.0.0.4 115 msec 116 msec']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...