python3 arp-scan и разбор mac - PullRequest
       33

python3 arp-scan и разбор mac

0 голосов
/ 22 ноября 2018

Я пытаюсь проанализировать MAC-адреса из вывода arp-scan.Вот пример:

import re
from subprocess import Popen, PIPE

def get_active_hosts():
    with Popen(['sudo', 'arp-scan', '-l', '-r', '5'], stdout = PIPE) as proc:
        mac_list = re.compile('\s+(([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]){2})\s+')
        mac_list = mac_list.findall(proc.stdout.read().decode('utf-8'))
    return mac_list
print(get_active_hosts())

Но я получил такой вывод:

[('4a:c3:26:0e:85:d0', '85:', '0')]

Что происходит?Как захватить только MAC-адреса без этой корзины:

[('85:', '0')]

Спасибо за совет.

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Давайте посмотрим на документацию по методу findall:

re.findall (pattern, string, flags = 0)

Вернуть все непересекающиеся совпадения pattern в строке, как список строк.Строка сканируется слева направо, и совпадения возвращаются в указанном порядке. Если в шаблоне присутствует одна или несколько групп, вернуть список групп;это будет список кортежей, если шаблон имеет более одной группы. Пустые совпадения включены в результат.

Изменено в версии 3.7: непустые совпадения теперь могут начинаться сразу после предыдущего пустогоmatch.

Обратите внимание на жирный текст.У вас есть несколько групп в шаблоне:

  • (([0-9A-Fa-f] {2}:) {5} ([0-9A-Fa-f]) => '4a: c3: 26: 0e: 85: d0'
  • ([0-9A-Fa-f] {2} :) => '85: '
  • ([0-9A-Fa-f]) => '0'

И, как сказано в документации, вы получите список кортежей с захваченными группами.

Чтобы получить только полный MAC-адрес, вам нуженукажите нефиксирующие скобки в регулярное выражение. Документация re гласит:

(?: ...) Версия фиксированных скобок без захвата. Соответствует любому регулярному выражениювнутри скобок, но подстрока, сопоставленная группой, не может быть извлечена после выполнения сопоставления или ссылки позже в шаблоне.

Итак, исправьте все неосновные скобки (которые не захватывают весь MAC-адрес).

0 голосов
/ 22 ноября 2018

findall возвращает все найденные подходящие группы.Группы объявляются с использованием набора круглых скобок.Ваше регулярное выражение содержит три группы следующим образом:

(([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]){2})
([0-9A-Fa-f]{2}:)
([0-9A-Fa-f])

Итак, теперь мы надеемся, что вы понимаете, почему findall дает вам три совпадения и почему они выглядят так, как они.

Решение здесьобъявить эти дополнительные группы (те, которые вы не хотите) без захвата , поставив ?: после открывающей скобки следующим образом:

mac_list = re.compile('\s+((?:[0-9A-Fa-f]{2}:){5}(?:[0-9A-Fa-f]){2})\s+')
...