2013-04-09 2 views
2

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

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

Device ID: RTPER1.MFN21Mb.domain.local 
Entry address(es): 
    IP address: 200.152.51.3 
    IP address: 82.159.177.233 
    IP address: 201.152.51.140 
    IP address: 84.252.100.3 
Platform: Cisco 2821, Capabilities: Router Switch IGMP 

Я написал это регулярное выражение, чтобы захватить ввод, и в соответствии с gskinner это соответствует всем 4 IP адреса, но захват только последний (как и следовало ожидать от регулярных выражений)

Device ID: ([0-9A-Za-z-.&]+)\s+Entry address\(es\):\s+(?:IP address: ([0-9.]+)\s+)+ 

Я вышли в интернет, чтобы выяснить, как это сделать. Я попробовал regex, предложенный здесь Capturing repeating subpatterns in Python regex, но с использованием модуля regex не изменил вывод. Я все еще получаю только последний IP-адрес в списке, и ни один из остальных.

Следуя примеру я

temp = regex.match(r'Device ID: ([0-9A-Za-z-.&]+)\s+Entry address\(es\):\s+(?:IP address: ([0-9.]+)\s+)+', file) 
print temp 

Temp возвращает None.

Если я нахожусь. Я получаю возврат только последний IP-адрес 84.252.100.3

Если добавить несколько групп захвата, такие как

temp = regex.findall(r'Device ID: ([0-9A-Za-z-.&]+)\s+Entry address\(es\):\s+(?:IP address: ([0-9.]+)\s+)?\s+(?:IP address: ([0-9.]+)\s+)?\s+(?:IP address: ([0-9.]+)\s+)?\s+(?:IP address: ([0-9.]+)\s+)?\s+(?:IP address: ([0-9.]+)\s+)?', file) 
print temp 

Это соответствует только те, которые имеют mutliple IP-адреса, а не другие

Надеюсь, кто-то может помочь.

+0

Вы уверены, что вы будете следовать примеру тесно? (regex module) – nhahtdh

+0

@nhahtdh Я обновил сообщение с ответами, которые получаю – iargue

+0

Используйте 'search' вместо' match'. 'match' всегда начинается с начала строки. – nhahtdh

ответ

1

Насколько я знаю, только .NET позволяет выполнять итерацию с помощью количественных (повторяющихся) групп захвата. Рассмотрим это (конечное) альтернатива:

Device ID: ([0-9A-Za-z-.&]+)\s+Entry address\(es\):\s+(?:IP address: ([0-9.]+)\s+)(?:IP address: ([0-9.]+)\s+)?(?:IP address: ([0-9.]+)\s+)?(?:IP address: ([0-9.]+)\s+)? 
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

Это будет улавливать до 1 IP-адрес в $2 и до трех более $3, $4 и $5. (Разумеется, я использую нотацию $). Вы можете добавить столько, сколько хотите. Если вам нужно все IP-адреса должны присутствовать в одной группе, т.е. $2, то ваш единственный выбор, чтобы включить текст с ними:

Device ID: ([0-9A-Za-z-.&]+)\s+Entry address\(es\):\s+((?:IP address: (?:[0-9.]+)\s+)+) 
                ^    ^^   ^
+0

Я не использовал его сам, но модуль 'regex' Python, похоже, позволяет получить список текста, захваченного группой, которая повторяется, в соответствии с ответом в вопросе, к которому относится OP. (Во всяком случае, первый вариант даже не вариант, ИМО, поскольку вы накладываете верхний предел) – nhahtdh

+1

@nhahtdh - Ах, моя ошибка. Я только прочитал первый ответ, и я сам не знаком с Питоном. Я узнаю ваше имя из прошлых обсуждений в регулярном выражении. Поэтому с должным уважением я не считаю, что введение верхнего предела делает вариант недействительным. Тем более, что (в настоящее время считается неправильным) предположение о том, что другого способа не существует, возможность указать регулярное выражение, которое может фиксировать до, скажем, 100 IP-адресов, может быть более чем достаточным для практических потребностей OP. –

+0

Я думаю, что более практично использовать второй вариант в вашем посте (возьмите весь блок однородных данных и используйте второй проход, чтобы извлечь его). Мое намерение состоит в том, чтобы препятствовать использованию первого подхода, если это не одноразовый бизнес. – nhahtdh

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