вызов разбора с несколькими строковыми форматами - PullRequest
0 голосов
/ 11 июля 2019

Я пытаюсь проанализировать журнал устройства, но формат не соответствует

Пример:

Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161  RSSI: -70

Roam candidate#10 F4:CF:E2:62:02:2F on channel 11  RSSI: -70

Я хочу получить адрес Mac, канал и значения RSSI
К сожалению, пробел пропускается после того, как значение кандидата становится равным 10 или выше.

Я пытался токенизировать его, но я едва понимаю этот процесс

def clean(string):
    result = ""
    for i,char in enumerate(line):
        if char == " ":
            if string[i+1].isdigit() or string[i+1] == " ":
                continue
        result += char
    return result

def tokenize(string):
    result = []
    previous = 0
    for i,char in enumerate(string):
        if char == " ":
            result.append(string[previous:i])
            previous = i+1
        elif i == len(string)-1:
            result.append(string[previous:i+1])
    return result

Я получаю только последний столбец (RSSI) в качестве вывода

Ответы [ 4 ]

1 голос
/ 11 июля 2019

Что-то простое может быть лучше

r"(?i)([a-f0-9]{2}(?::[a-f0-9]{2})+)\s.*?\s(\d+)\s.*?\s(-?\d+)"

https://regex101.com/r/smcjY5/1

Расширен

 (?i)
 (                             # (1 start)
      [a-f0-9]{2} 
      (?: : [a-f0-9]{2} )+
 )                             # (1 end)
 \s .*? \s 
 ( \d+ )                       # (2)
 \s .*? \s 
 ( -? \d+ )                    # (3)
1 голос
/ 11 июля 2019

Если вы хотите использовать шаблон, вы можете использовать 3 группы захвата, 1 для MAC-адреса, 1 для канала и 1 для значений RSSI:

Roam candidate# ?\d+ ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]){2}) on channel (\d+) +RSSI: (-?\d+)

В меньших частях:

  • Roam candidate# ?\d+ Соответствие Кандидат в роуминг # , дополнительный пробел и цифры 1+
  • ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]){2}) Группа захвата 1, совпадает с MAC-адресом
  • on channel (\d+) + Совпадение на канале , пробел с последующим захватом в группе 2 1+ цифры
  • RSSI: (-?\d+) Совпадение RSSI: , пробел и захват в группе 3 необязательно - и 1+ цифры

Regex demo | Демонстрация Python

Например

import re

strings = ["Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161  RSSI: -70", "Roam candidate#10 F4:CF:E2:62:02:2F on channel 11  RSSI: -70"]
regex = r"Roam candidate# ?\d+ ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]){2}) on channel (\d+) +RSSI: (-?\d+)"
for s in strings:
    print(re.findall(regex, s, re.M))

Результат

[('F4: CF: E2: 5E: 73: 3F', '161', '-70')]

[('F4: CF: E2: 62: 02: 2F', '11', '-70')]

0 голосов
/ 11 июля 2019

Другой подход регулярного выражения:

import re

lines = '''Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161  RSSI: -70
Roam candidate#10 F4:CF:E2:62:02:2F on channel 11  RSSI: -70'''

pat = re.compile(r'(?<=#)\s*\d+\s+((?:[A-F0-9]{2}:){5}[A-F0-9]{2}) .*channel\s+(\d+)\s+RSSI:\s+(-?\d+)', re.I)
for line in lines.split('\n'):
    print(pat.findall(line))

Выход:

[('F4:CF:E2:5E:73:3F', '161', '-70')]
[('F4:CF:E2:62:02:2F', '11', '-70')]
0 голосов
/ 11 июля 2019

С регулярным выражением это будет работать так:

import re
s1="Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161 RSSI: -70"
s2="Roam candidate#10 F4:CF:E2:62:02:2F on channel 11 RSSI: -70"

patt= re.compile('(?P<mac>[0-9A-F]{2}(:[0-9A-F]{2}){5}).*?channel (?P<channel>[0-9]*).*?RSSI:\s*(?P<rssi>-?[0-9]*)', re.I)

matcher= patt.search(s1)

print(matcher.group('mac'))
print(matcher.group('channel'))
print(matcher.group('rssi'))

Возвращает:

F4:CF:E2:5E:73:3F
161
-70

А для второй строки:

F4:CF:E2:62:02:2F
11
-70
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...