Ломаю голову по этому поводу уже 2 дня. Я пытаюсь сопоставить содержимое пакета с API регулярных выражений:
packet_re = (r'.*RADIUS.*\s*Accounting(\s|-)Request.*(Framed(\s|-)IP(\s|-)Address.*Attribute.*Value: (?P<client_ip>\d+\.\d+\.\d+\.\d+))?.*(Username|User-Name)(\s|-)Attribute.*Value:\s*(?P<username>\S+).*')
packet1 = """
IP (tos 0x0, ttl 64, id 35592, offset 0, flags [DF], proto UDP (17), length 213)
10.10.10.1.41860 > 10.10.10.3.1813: [udp sum ok] RADIUS, length: 185
Accounting-Request (4), id: 0x0a, Authenticator: 41b3b548c4b7f65fe810544995620308
Framed-IP-Address Attribute (8), length: 6, Value: 10.10.10.11
0x0000: 0a0a 0a0b
User-Name Attribute (1), length: 14, Value: 005056969256
0x0000: 3030 3530 3536 3936 3932 3536
"""
result = search(packet_re, packet1, DOTALL)
Регулярное выражение соответствует, но не может захватить Framed-IP-Address Attribute, client_ip=10.10.10.11. Дело в том, что Framed-IP-Address Attribute может или не может прийти в пакет. Следовательно, шаблон заключен в другую группу захвата, оканчивающуюся на ?, что означает 0 или 1 вхождение.
Я должен быть в состоянии игнорировать его, когда он не приходит. Следовательно, содержимое пакета также может быть:
packet2 = """
IP (tos 0x0, ttl 64, id 60162, offset 0, flags [DF], proto UDP (17), length 163)
20.20.20.1.54035 > 20.20.20.2.1813: [udp sum ok] RADIUS, length: 135
Accounting-Request (4), id: 0x01, Authenticator: 219b694bcff639221fa29940e8d2a4b2
User-Name Attribute (1), length: 14, Value: 005056962f54
0x0000: 3030 3530 3536 3936 3266 3534
"""
В этом случае регулярное выражение должно игнорировать Framed-IP-Address. Он игнорирует, но не фиксирует, когда приходит.
Я не могу отблагодарить вас достаточно. С вашим ответом тоже есть чему поучиться. Спасибо.






я предлагаю использовать
RADIUS.*?Accounting[\s-]Request(?:.*?(Framed[\s-]IP[\s-]Address.*?Attribute(?:.*?Value: (?P<client_ip>\d+\.\d+\.\d+\.\d+))?))?.*User-?[nN]ame[\s-]Attribute.*?Value:\s*(?P<username>\S+)
Посмотрите демонстрацию регулярного выражения .
Обратите внимание, что я удалил .* на обоих концах шаблона, поскольку вы используете re.search, который не требует сопоставления в начале строки, такой как re.match, а объект MatchData содержит свойство .string, к которому вы можете получить доступ, чтобы получить всю входную строку.
Подробности
RADIUS - слово.*? - любой ноль или более символов, как можно меньшеAccounting - слово[\s-] - пробел или дефисRequest - слово(?:.*? - начало необязательной группы без захвата: любой ноль или более символов как можно меньше, затем...
(Framed[\s-]IP[\s-]Address.*?Attribute - Группа 1: Framed + пробел или дефис + IP + пробел/дефис + Address + любой ноль или более символов как можно меньше + Attribute(?:.*?Value: (?P<client_ip>\d+\.\d+\.\d+\.\d+))? - необязательная группа без захвата, соответствующая любому нулю или более символов как можно меньше + Value: + группа "client_ip": четыре шаблона соответствия одной или более цифр, разделенные буквенной точкой) - окончание группы 1)? - конец внешней незахватывающей группы.* - любые ноль или более символов как можно большеUser-?[nN]ame - Username, UserName или User-name/User-Name[\s-] - пробел или дефисAttribute - слово.*? - любые ноль или более символов как можно меньшеValue: - литеральная строка\s* - ноль или более пробелов(?P<username>\S+) — Группа «имя пользователя»: один или несколько символов без пробелов.Здравствуйте, @Wiktor Stribiżew, извините за ковыряние, но мне было интересно, почему это не работает: RADIUS.*?Accounting[\s-]Request(?:.*?(Framed[\s-]IP[\s-]Address.*?Attribute.*?Value: (?P<client_ip>\d+\.\d+\.\d+\.\d+))?)?.*User-?[nN]ame[\s-]Attribute.*?Value:\s*(?P<username>\S+) т. е. зачем нам нужна еще одна необязательная группа без захвата Value: 10.10.10.11, а не просто захват client_ip как есть.
@tcpip На самом деле, я не уверен, почему я обернул эту часть необязательной группировкой, и на самом деле, RADIUS.*?Accounting[\s-]Request(?:.*?(Framed[\s-]IP[\s-]Address.*?Attribute.*?Value: (?P<client_ip>\d+\.\d+\.\d+\.\d+)))?.*User-?[nN]ame[\s-]Attribute.*?Value:\s*(?P<username>\S+)тоже работает. Ваша точка зрения не работает, потому что вы делаете только группу необязательной, но вам нужно обернуть группу И ее правую часть .*/.*? группой без захвата, чтобы заставить механизм регулярных выражений попробовать этот шаблон хотя бы один раз. .
Похоже, вы можете использовать
RADIUS.*?Accounting[\s-]Request(?:.*?(Framed[\s-]IP[\s-]Address.*?Attribute(?:.*?Value: (?P<client_ip>\d+\.\d+\.\d+\.\d+))?))?.*User-?[nN]ame[\s-]Attribute.*?Value:\s*(?P<username>\S+)- regex101.com/r/HGxPzW/1. Вам не нужно.*в начале и конце, потому что даже если вам нужно, чтобы вся строка присутствовала в совпадении, вы можете использоватьresult.stringдля ее получения.