Python中的正则表达式完全匹配与组匹配

2024-09-30 03:24:46 发布

您现在位置:Python中文网/ 问答频道 /正文

以下摘录UDP作为第3组

([0-9A-F]{2}){5}([0-9A-F]{6}。)(\b[A-Z]{3})

以下提取物Q作为第3组

(\d+[abc]+\s{3})(\b[A-Z])

以下摘录ASOA作为第2组

(]+\s)(\b[A-Z])

7/26/2020 11:59:20 PM 2C0C PACKET  00000137F00E6B40 UDP Rcv 192.168.2.182   994c   Q [0001   D   NOERROR] A      (8)metadata(6)google(8)internal(0)
7/26/2020 11:59:20 PM 2B10 PACKET  00000121F00F92A0 UDP Rcv 127.0.0.1       1617   Q [0001   D   NOERROR] SOA    (6)_msdcs(6)microsoft(3)com(0)
7/26/2020 11:59:20 PM 24BC PACKET  0000019926F82050 UDP Rcv 192.168.10.20   5e0e   Q [0001   D   NOERROR] A      (4)wpad(5)win(2)jp(7)google(3)com(0)
7/26/2020 11:59:20 PM 1464 PACKET  00000192F00E6880 UDP Rcv 127.0.0.1       9937   Q [0001   D   NOERROR] SOA    (36)f4f036d7-238e-43a9-98f8-a76594be9ed9(6)_msdcs(6)yahoo(3)com(0)

如何改进每个正则表达式,使其与每个正则表达式完全匹配


Tags: compacketgooglemicrosoftinternaludpmetadataabc
1条回答
网友
1楼 · 发布于 2024-09-30 03:24:46

你的第一句话:

([0-9A-F]{2}){5}([0-9A-F]{6}.)(\b[A-Z]{3})

似乎匹配2*5个十六进制字符,后跟其中6个(总共16个),后跟任何单个字符,然后匹配单词边界后的三个大写字母。然而,看起来您真的希望在16个十六进制字符和协议之间有一个空白字符。因此,您可以从以下位置匹配第一组:

(?:[0-9A-F]{16})\s([A-Z]{3})

类似地,要获得'Q'(或其位置上的任何字符)和'A'或'SOA',可以说它是第一个[之前的最后一个[A-Z]序列和第一个]之后的第一个[A-Z]序列

然后整个表达式变成:

(?:[0-9A-F]{16})\s([A-Z]{3}).*([A-Z]+)\s\[.*?\]\s([A-Z]+)

从中您需要第1、2和3组。在python中:

import re

lines = [
    '7/26/2020 11:59:20 PM 2C0C PACKET  00000137F00E6B40 UDP Rcv 192.168.2.182   994c   Q [0001   D   NOERROR] A      (8)metadata(6)google(8)internal(0)',
    '7/26/2020 11:59:20 PM 2B10 PACKET  00000121F00F92A0 UDP Rcv 127.0.0.1       1617   Q [0001   D   NOERROR] SOA    (6)_msdcs(6)microsoft(3)com(0)',
    '7/26/2020 11:59:20 PM 24BC PACKET  0000019926F82050 UDP Rcv 192.168.10.20   5e0e   Q [0001   D   NOERROR] A      (4)wpad(5)win(2)jp(7)google(3)com(0)',
    '7/26/2020 11:59:20 PM 1464 PACKET  00000192F00E6880 UDP Rcv 127.0.0.1       9937   Q [0001   D   NOERROR] SOA    (36)f4f036d7-238e-43a9-98f8-a76594be9ed9(6)_msdcs(6)yahoo(3)com(0)'
]

rgx = re.compile(r'.*?(?:[0-9A-F]{16})\s([A-Z]{3}).*([A-Z]+)\s\[.*?\]\s([A-Z]+).*')
for line in lines:
    match = rgx.match(line)
    if not match:
        print('Something is wrong')
    else:
        print(match.group(1), match.group(2), match.group(3))

结果:

UDP Q A
UDP Q SOA
UDP Q A
UDP Q SOA

正如@41686d6564所指出的,您可以省略非捕获组:

rgx = re.compile(r'.*?[0-9A-F]{16}\s([A-Z]{3}).*([A-Z]+)\s\[.*?\]\s([A-Z]+).*')

此外,如果您只是将所有内容作为单个文本块,这是一种简洁的方式:

import re

lines = '7/26/2020 11:59:20 PM 2C0C PACKET  00000137F00E6B40 UDP Rcv 192.168.2.182   994c   Q [0001   D   NOERROR] A      (8)metadata(6)google(8)internal(0)\n' \
        '7/26/2020 11:59:20 PM 2B10 PACKET  00000121F00F92A0 UDP Rcv 127.0.0.1       1617   Q [0001   D   NOERROR] SOA    (6)_msdcs(6)microsoft(3)com(0)\n' \
        '7/26/2020 11:59:20 PM 24BC PACKET  0000019926F82050 UDP Rcv 192.168.10.20   5e0e   Q [0001   D   NOERROR] A      (4)wpad(5)win(2)jp(7)google(3)com(0)\n' \
        '7/26/2020 11:59:20 PM 1464 PACKET  00000192F00E6880 UDP Rcv 127.0.0.1       9937   Q [0001   D   NOERROR] SOA    (36)f4f036d7-238e-43a9-98f8-a76594be9ed9(6)_msdcs(6)yahoo(3)com(0)'


rgx = re.compile(r'[0-9A-F]{16}\s([A-Z]{3}).*([A-Z]+)\s\[.*?\]\s([A-Z]+)')
for match in rgx.findall(lines):
    print(match[0], match[1], match[2])

相关问题 更多 >

    热门问题