Предполагая, что ваше регулярное выражение довольно простое, без групп, обратных ссылок, подсказок и т. Д., Например, как в вашем случае, следуя шаблону \w[+*?]?
, вы можете сначала разбить его на части, как вы уже это делаете.Но затем вместо того, чтобы итеративно объединять части и сопоставлять их со всей строкой, вы можете проверить каждую часть по отдельности, нарезав уже соответствующие части.
def match(pattern, string):
res = pat = ""
for p in re.findall(r"\w[+*?]?", pattern):
m = re.match(p, string)
if m:
g = m.group()
string = string[len(g):]
res, pat = res + g, pat + p
else:
break
return pat, res
Пример:
>>> for s in "MMMV", "MMVVTTZ", "MTTZZZ", "MVZZZ", "MVTZX":
>>> print(*match("M+V?T*Z+", s))
...
M+V?T* MMMV
M+V?T* MMV
M+V?T*Z+ MTTZZZ
M+V?T*Z+ MVZZZ
M+V?T*Z+ MVTZ
Тем не менее, обратите внимание, что в худшем случае, если строка длиной n
и шаблон из n
частей, каждая из которых соответствует только одному символу, это все равно будет иметь значение O (n²) для многократного разрезания строки.
Кроме того, это может завершиться ошибкой, если две последовательные части имеют примерно один и тот же символ, например, a?a+b
(который должен быть эквивалентным a+b
) не будет соответствовать ab
, но только aab
поскольку сингл a
уже «потребляется» a?
.
Вы можете уменьшить сложность до O (n), написав свой собственный очень простой метод сопоставления регулярных выражений для этого очень сокращенного вида регулярных выражений,но в среднем случае это может не стоить того или даже медленнее.