Python 正则表达式问题,中间有可选子字符串

tcp*_*pip 5 python regex

两天以来我一直在为此烦恼。我正在尝试将数据包内容与正则表达式 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)
Run Code Online (Sandbox Code Playgroud)

正则表达式匹配,但无法捕获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
"""
Run Code Online (Sandbox Code Playgroud)

在这种情况下,正则表达式应忽略 Framed-IP-Address。它确实会忽略,但不会捕获它何时到来。

Wik*_*żew 2

我建议使用

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+)
Run Code Online (Sandbox Code Playgroud)

请参阅正则表达式演示

注意,我删除了.*模式的两端,因为您使用的模式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 - UsernameUserName或者User-name/User-Name
  • [\s-]- 空格或连字符
  • Attribute- 一个字
  • .*?- 任何零个或多个尽可能少的字符
  • Value:- 文字字符串
  • \s*- 零个或多个空格
  • (?P<username>\S+)- 组“用户名”:一个或多个非空白字符