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

python:regex-捕获组的可变数量,python,regex,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]+\]=)\s+<(([A-Z_0-9]+

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

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]+\]=)\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)
将匹配最新字段

演示:


注意:如果您不想要某些组,您最好使用非捕获组,方法是在捕获组的前导添加
?:
(?:…)),并注意
(0x[0-9]+|0):\s+
作为正则表达式中的额外组(基于您的输入模式)

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

([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)
将匹配最新字段

演示:


注意:如果您不想使用某些组,您最好使用非捕获组,方法是在捕获组的前面添加
?:
(?:…)),并注意
(0x[0-9]+|0):\s+
作为正则表达式中的额外部分(基于您的输入模式)

简言之,在
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'}}

我个人建议去掉“TABLE_ENTRY”,因为它是重复的,但如您所愿。

简而言之,在
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'}}

我个人建议去掉“TABLE_ENTRY”,因为它是重复的,但可以根据您的意愿进行。您寻求的最终输出是什么?在问题中举个例子。您能举个具体的例子吗?您问题中的文本似乎是一种语法描述,而不是示例,对吗?您确定您的regexp的
0x[0-9]+
-部分吗?因为那应该是一个十六进制数,所以我更喜欢
0x[0-9A-Fa-f]+
!你寻求的最终结果是什么?在问题中举个例子。你能举个具体的例子吗?您问题中的文本似乎是一种语法描述,而不是示例,对吗?您确定您的regexp的
0x[0-9]+
-部分吗?因为那应该是一个十六进制数,所以我更喜欢
0x[0-9A-Fa-f]+
!每天我都会重新发现python是多么轻松,谢谢。如果我从输入字符串中删除新行,它将不再捕获2个匹配项,这是为什么?我得到:('TABLE_ENTRY.0','0x3242','FIELD_1=0x1234,FIELD_2=0x1234,FIELD_3=0x1234>TABLE_ENTRY.1[0x1235]=0x98789:应该是\s+]*)>而不是\s+固定。请记住,您最初的规范使用的是
\n
。每天我都会重新发现python是多么轻松,谢谢。如果我从输入字符串中删除新行,它将不再捕获2个匹配项,这是为什么?我得到:('TABLE_ENTRY.0','0x3242','FIELD_1=0x1234,FIELD_2=0x1234,FIELD_3=0x1234>TABLE_ENTRY.1[0x1235]=0x98789:应该是\s+]*)>而不是\s+固定。请记住,您的原始规范使用了
\n
(([A-Z_0-9]+)=(0x[0-9]+|0),\s?)*
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'