python:regex - 捕获可变数量的组

时间:2016-09-23 19:27:17

标签: python regex

我有一个看起来像的字符串:

TABLE_ENTRY.0[hex_number]= <FIELD_1=hex_number, FIELD_2=hex_number..FIELD_X=hex>
TABLE_ENTRY.1[hex_number]= <FIELD_1=hex_number, FIELD_2=hex_number..FIELD_Y=hex>

字段数量未知,因入门而异,我想要捕获 每个条目分别包含其所有字段及其值。

我想出了:

([A-Z_0-9\.]+\[0x[0-9]+\]=)(0x[0-9]+|0):\s+<(([A-Z_0-9]+)=(0x[0-9]+|0))

匹配表条目和第一个字段,但我不知道如何考虑可变数量的字段。

输入:

ENTRY_0[0x130]=0: <FIELD_0=0, FIELD_1=0x140... FIELD_2=0xff3>
输出应该是:

ENTRY 0:
        FIELD_0=0
        FIELD_1=0x140
        FIELD_2=ff3
ENTRY 1:
        ...

2 个答案:

答案 0 :(得分:3)

简而言之,在re引擎中无法完成所有这些操作。您无法动态生成更多组。它将全部放在一个组中。你应该重新解析结果:

import re
input_str = ("TABLE_ENTRY.0[0x1234]= <FIELD_1=0x1234, FIELD_2=0x1234, FIELD_3=0x1234>\n"
             "TABLE_ENTRY.1[0x1235]= <FIELD_1=0x1235, FIELD_2=0x1235, FIELD_3=0x1235>")
results = {}
for match in re.finditer(r"([A-Z_0-9\.]+\[0x[0-9A-F]+\])=\s+<([^>]*)>", input_str):
    fields = match.group(2).split(", ")
    results[match.group(1)] = dict(f.split("=") for f in fields)

>>> results
{'TABLE_ENTRY.0[0x1234]': {'FIELD_2': '0x1234', 'FIELD_1': '0x1234', 'FIELD_3': '0x1234'}, 'TABLE_ENTRY.1[0x1235]': {'FIELD_2': '0x1235', 'FIELD_1': '0x1235', 'FIELD_3': '0x1235'}}

输出只是一个大型字典,由一个表条目和一个字段的字典组成。

你也可以这样做很方便:

>>> results["TABLE_ENTRY.0[0x1234]"]["FIELD_2"]
'0x1234'

我个人建议剥离“TABLE_ENTRY”,因为它是重复的,但是如你所愿。

答案 1 :(得分:1)

使用捕获组来匹配不合适的长度:

([A-Z_0-9\.]+\[0x[0-9]+\]=)\s+<(([A-Z_0-9]+)=(0x[0-9]+|0),\s?)*([A-Z_0-9]+)=(0x[0-9]+|0)

以下部分匹配具有尾随逗号和空格的每个字段数

(([A-Z_0-9]+)=(0x[0-9]+|0),\s?)*

([A-Z_0-9]+)=(0x[0-9]+|0)将匹配最新字段。

演示:https://regex101.com/r/gP3oO6/1

注意:如果您不想要某些群组,最好通过在捕获群组的前导处添加?:来使用非捕获群组。((?: ...)),并注意(0x[0-9]+|0):\s+ 1}}作为你的正则表达式中的额外内容(基于你的输入模式)