Python正则表达式捕获多组N次

Python regex capture multiple groups N number of times

我正在解析一个进程的 /proc/PID/stat。该文件的输入为:

25473 (firefox) S 25468 25465 25465 0 -1 4194304 149151169 108282 32 15 2791321 436115 846 86 20 0 84 0 9648305 2937786368 209665 18446744073709551615 93875088982016 93875089099888 140722931705632 140722931699424 140660842079373 0 0 4102 33572009 0 0 0 17 1 0 0 175 0 0 93875089107104 93875089109128 93875116752896 140722931707410 140722931707418 140722931707418 140722931707879 0

我想到了:

import re

def get_stats(pid):
    with open('/proc/{}/stat'.format(pid)) as fh:
        stats_raw = fh.read()
    stat_pattern = '(\d+\s)(\(.+\)\s)(\w+\s)(-?\d+\s?)'
    return re.findall(stat_pattern, stats_raw)

这将匹配前三组,但只有 return 最后一组 (-?\d+\s?) 的一个字段:

[('25473 ', '(firefox) ', 'S ', '25468 ')]

我正在寻找一种方法来仅匹配最后一组的设置数字:

'(\d+\s)(\(.+\)\s)(\w+\s)(-?\d+\s?){49}'

您无法使用 re 正则表达式访问每个重复的捕获。您可以将整个字符串的其余部分捕获到第 4 组,然后用空格拆分:

import re
s = r'25473 (firefox) S 25468 25465 25465 0 -1 4194304 149151169 108282 32 15 2791321 436115 846 86 20 0 84 0 9648305 2937786368 209665 18446744073709551615 93875088982016 93875089099888 140722931705632 140722931699424 140660842079373 0 0 4102 33572009 0 0 0 17 1 0 0 175 0 0 93875089107104 93875089109128 93875116752896 140722931707410 140722931707418 140722931707418 140722931707879 0'
stat_pattern = r'(\d+)\s+(\([^)]+\))\s+(\w+)\s*(.*)'
res = []
for m in re.finditer(stat_pattern, s):
    res.append(m.group(1))
    res.append(m.group(2))
    res.append(m.group(3))
    res.extend(m.group(4).split())
print(res)

输出:

['25473', '(firefox)', 'S', '25468', '25465', '25465', '0', '-1', '4194304', '149151169', '108282', '32', '15', '2791321', '436115', '846', '86', '20', '0', '84', '0', '9648305', '2937786368', '209665', '18446744073709551615', '93875088982016', '93875089099888', '140722931705632', '140722931699424', '140660842079373', '0', '0', '4102', '33572009', '0', '0', '0', '17', '1', '0', '0', '175', '0', '0', '93875089107104', '93875089109128', '93875116752896', '140722931707410', '140722931707418', '140722931707418', '140722931707879', '0']

如果您只需要将 49 个号码放入第 4 组,请使用

r'(\d+)\s+(\([^)]+\))\s+(\w+)\s*((?:-?\d+\s?){49})'
                                ^^^^^^^^^^^^^^^^^^

使用 PyPi regex module,您可以使用 r'(?P<o>\d+)\s+(?P<o>\([^)]+\))\s+(?P<o>\w+)\s+(?P<o>-?\d+\s?){49}' 并在 运行 之后使用 regex.search(pattern, s) 访问 .captures("o") 堆叠您需要的值。

>>> import regex
>>> s = '25473 (firefox) S 25468 25465 25465 0 -1 4194304 149151169 108282 32 15 2791321 436115 846 86 20 0 84 0 9648305 2937786368 209665 18446744073709551615 93875088982016 93875089099888 140722931705632 140722931699424 140660842079373 0 0 4102 33572009 0 0 0 17 1 0 0 175 0 0 93875089107104 93875089109128 93875116752896 140722931707410 140722931707418 140722931707418 140722931707879 0'
>>> stat_pattern = r'(?P<o>\d+)\s+(?P<o>\([^)]+\))\s+(?P<o>\w+)\s+(?P<o>-?\d+\s?){49}'
>>> m = regex.search(stat_pattern, s)
>>> if m:
    print(m.captures("o"))

输出:

['25473', '(firefox)', 'S', '25468 ', '25465 ', '25465 ', '0 ', '-1 ', '4194304 ', '149151169 ', '108282 ', '32 ', '15 ', '2791321 ', '436115 ', '846 ', '86 ', '20 ', '0 ', '84 ', '0 ', '9648305 ', '2937786368 ', '209665 ', '18446744073709551615 ', '93875088982016 ', '93875089099888 ', '140722931705632 ', '140722931699424 ', '140660842079373 ', '0 ', '0 ', '4102 ', '33572009 ', '0 ', '0 ', '0 ', '17 ', '1 ', '0 ', '0 ', '175 ', '0 ', '0 ', '93875089107104 ', '93875089109128 ', '93875116752896 ', '140722931707410 ', '140722931707418 ', '140722931707418 ', '140722931707879 ', '0']