2016-12-14 3 views
1

Я разбираю /proc/PID/stat процесса. Файл имеет вход:Python regex захватить несколько групп N количество раз

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) 

Это будет соответствовать первые три группы, но возвращать только одно поле для последней группы (-?\d+\s?):

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

Я искал способ согласования только определенного номера для последней группы:

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

Можно ли использовать модуль регулярных выражений PyPi? Затем вы можете использовать свой подход. Иначе вам понадобится два шага. –

+0

@ WiktorStribiżew хорошо знать об этом модуле, но это часть другого модуля, и было бы нецелесообразно добавлять другую зависимость. Хотя вы показываете разницу в ответе, не будет плохой идеей, если кто-то еще столкнется с этим. – tijko

+1

Итак, используйте '' (\ d + \ s) (\ (. + \) \ S) (\ w + \ s) ((?: -? \ D + \ s?) {49}) '' и после получения матчи, разделили 4-ю группу с пробелами. –

ответ

1

Вы не можете получить доступ к каждому повторному захвату с помощью регулярного выражения 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']

Смежные вопросы