Python регулярное выражение с переменной - PullRequest
2 голосов
/ 02 мая 2020

Я пишу код для разбора SVG transform команды в Python3 .7:

t = "translate(44,22) rotate(55,6,7) scale(2)"
num = "[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?" 
types = "matrix|translate|rotate|scale|skewX|skewY"
regex = f"({types})\((?P<arg1>{num})(?:,?(?P<argi>{num}))*\)" # <- 'i' as an increasing number
matches = re.finditer(regex, t)
print(match.groupdict())

types во входной строке t может иметь до 6 параметров внутри круглые скобки (у «матрицы» 6, у других меньше). Я хотел бы использовать groupdict(), чтобы дать мне пронумерованные аргументы arg-1, arg-2, arg-3, et c. в зависимости от того, сколько finditer нашел. Это означает, что именованное соответствие должно быть переменной, которая увеличивается.

Я попробовал некоторые очевидные вещи и посмотрел документы. Ни один из них не помог мне.

Так ... это возможно? Я думаю об этом неправильно? Спасибо!

Ответы [ 2 ]

1 голос
/ 02 мая 2020

Если в скобках может быть только до 6 аргументов, используйте шесть (?:,(?P<argX>{num}))? необязательных групп (где X - это di git от 1 до 6), чтобы сопоставить от 1 до 6 шаблонов, соответствующих аргументам, и затем отбросьте все элементы группового приговора, которые имеют None значение:

import re
t = "translate(44,22) rotate(55,6,7) scale(2)"
num = "[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?" 
types = "matrix|translate|rotate|scale|skewX|skewY"
regex = f"({types})\((?P<arg1>{num})(?:,(?P<arg2>{num}))?(?:,(?P<arg3>{num}))?(?:,(?P<arg4>{num}))?(?:,(?P<arg5>{num}))?(?:,(?P<arg6>{num}))?\)" # <- 'i' as an increasing number
for match in re.finditer(regex, t):
    print({k:v for k,v in match.groupdict().items() if v is not None})

См. Python демо , уступающее

{'arg1': '44', 'arg2': '22'}
{'arg1': '55', 'arg2': '6', 'arg3': '7'}
{'arg1': '2'}
0 голосов
/ 02 мая 2020

Может быть, вы можете использовать ast.literal_eval с re для анализа параметров, например:

import re
from ast import literal_eval

t = "translate(44,22) rotate(55,6,7) scale(2)"
types = "matrix|translate|rotate|scale|skewX|skewY"

print([(f, literal_eval('(' + s + ',)')) for f, s in re.findall(fr'({types})\(([^)]+)', t)])

Отпечатки:

[('translate', (44, 22)), ('rotate', (55, 6, 7)), ('scale', (2,))]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...