Я хотел бы упростить приведенную ниже логику регулярных выражений с помощью одного оператора регулярного выражения. Тогда легче понять логику.
import re
content = """
[ 1.765989] initcall init_module.cfi_jt+0x0/0x8 [altmode_glink] returned 0 after 379 usecs
[ 0.001873] initcall selinux_init+0x0/0x1f8 returned 0 after 85 usecs
"""
for line in content.split("\n"):
m = re.search("\[\s+(?P<ts>[\d.]+)\] initcall init_module.*\[(?P<func>[^ ]+)\] returned (?P<ret>[\d-]+) after (?P<val>[\d-]+) usecs",line)
if m:
ts = m['ts']
func = m['func']
ret = m['ret']
val = m['val']
print(ts,func,ret,val)
else:
m = re.search("\[\s+(?P<ts>[\d.]+)\] initcall (?P<func>[^ ]+)\+.*? returned (?P<ret>[\d-]+) after (?P<val>[\d-]+) usecs",line)
if m:
ts = m['ts']
func = m['func']
ret = m['ret']
val = m['val']
print(ts,func,ret,val)
Текущий выход хороший:
1.765989 altmode_glink 0 379
0.001873 selinux_init 0 85
Очевидно, что эти два шаблона очень похожи, используйте '|' если они различаются, попробуйте следующее:
import re
content = """
[ 1.765989] initcall init_module.cfi_jt+0x0/0x8 [altmode_glink] returned 0 after 379 usecs
[ 0.001873] initcall selinux_init+0x0/0x1f8 returned 0 after 85 usecs
"""
pattern = re.compile(
r"\[\s+(?P<ts>[\d.]+)\] initcall (init_module.*\[(?P<func>[^ ]+)\]|(?P<func>[^ ]+)\+.*) returned (?P<ret>[\d-]+) after (?P<val>[\d-]+) usecs"
)
for line in content.split("\n"):
m = pattern.search(line)
if m:
ts = m['ts']
func = m['func']
ret = m['ret']
val = m['val']
print(ts, func, ret, val)
Предлагаю вам протестировать свой код перед публикацией.
сообщить об ошибке: re.error: переопределение имени группы «func» как группы 4; был в группе 3 на позиции 69
Другая версия с использованием одного шаблона (ссылка regex101):
import re
content = """
[ 1.765989] initcall init_module.cfi_jt+0x0/0x8 [altmode_glink] returned 0 after 379 usecs
[ 0.001873] initcall selinux_init+0x0/0x1f8 returned 0 after 85 usecs
"""
pattern = r"(?P<ts>[\d.]+).*(?P<func>(?<= )\S+(?=\+)|(?<=\[)[^\]]+).*?returned (?P<ret>\d+) after (?P<val>\d+)"
for m in re.finditer(pattern, content):
print(m["ts"])
print(m["func"])
print(m["ret"])
print(m["val"])
print()
Распечатки:
1.765989
altmode_glink
0
379
0.001873
selinux_init
0
85
Сложная часть, по-видимому, заключается в том, как вы определяете имя функции, которому могут соответствовать символы, отличные от левой скобки, за которыми следует либо правая скобка, либо знак плюса, за которым следуют непробелы:
for ts, func, ret, val in re.findall(
r'\[\s*([\d.]+)] initcall .*?([^[]+)(?:]|\+\S+) '
r'returned (\d+) after (\d+) usecs', content):
print(ts, func, ret, val)
Это выводит:
1.765989 altmode_glink 0 379
0.001873 selinux_init 0 85
Демо здесь
Почему отрицательный голос? Это хороший ответ... +1
r"\[\s+(?P<ts>[\d.]+)\] initcall.+(\[)?\b(?P<func>[^][\s+]+)(?(2)]|\+.*?) returned (?P<ret>[\d-]+) after (?P<val>[\d-]+) usecs"