-2

我正在尝试解析readelf输出:

import re
o = '      EXIDX          0x000590 0x002c0590 0x002c0590 0x00008 0x00008 R   0x4'
re.findall(r'^ \s+ (\w+) \s+ (?:(0x [\da-f]+ )\s+)+', o, re.VERBOSE) # (1)
# [('EXIDX', '0x00008')]

为什么只捕获一个十六进制数?我期望

re.findall(r'^ \s+ (\w+) \s+ (?:(0x [\da-f]+ )\s+)+', o, re.VERBOSE) 
# [('EXIDX', '0x000590', '0x002c0590', '0x002c0590', '0x00008', '0x00008')]

当我尝试使用此 RE 时,它至少给出了仅匹配第一个数字的可理解结果:

re.findall(r'^ \s+ (\w+) \s+ (0x [\da-f]+ )\s+', oo, re.VERBOSE)
# [('EXIDX', '0x000590')]

我不明白为什么我只得到带有 RE (1) 的最后一个 (?) 数字

4

2 回答 2

1

匹配多个模式时,捕获组不会成倍增加。他们只捕获一次,在这种情况下匹配的最后一个模式。

捕获所有十六进制数,然后拆分结果:

o = '      EXIDX          0x000590 0x002c0590 0x002c0590 0x00008 0x00008 R   0x4'
[[r[0]] + r[1].split() for r in re.findall(r'^ \s+ (\w+) \s+ ((?:0x [\da-f]+ \s+)*)', o, re.VERBOSE)]

输出

[['EXIDX', '0x000590', '0x002c0590', '0x002c0590', '0x00008', '0x00008']]

另一种方法是定义 6 个组,一个用于前导EXIDX模式,每个 1 个用于 5 个十六进制模式,但这会将您的模式锁定为 5 个十六进制值而不是可变数字。

于 2013-08-12T09:38:02.940 回答
0

好的,最后我发现我需要将所有数字抓成一组,然后将其拆分(感谢这个问题和 Martijn Pieters)

正确的代码是

r = re.findall(r'^ \s+ (\w+) \s+ ((?:0x [\da-f]+ \s+)*)', oo, re.VERBOSE)
numbers = r[0][1].split()
于 2013-08-12T09:45:51.653 回答