import re
def scan_compile(pattern):
pattern = pattern.replace('{str}', '(.+?)')
return re.compile(pattern.replace('{int}', '(\d+)'))
def scan_match(r, s):
match = r.match(s)
return [int(g) if g.isdigit() else g
for g in match.groups()]
>>> from scan_match import *
>>> r = scan_compile("{str} {int} {int}/{int}")
>>> scan_match(r, 'Mary Rose Jesus 12 24/32')
['Mary Rose Jesus', 12, 24, 32]
Для «времени» в формате часы: минуты еще по строчке в каждую функцию придется добавить… Конечно можно заморочиться, раздать всем группам имена типа «int_1», «datetime_2» еще с пяток типов, а при разборе все это учитывать. Тут как всегда: или простота, или гибкость.
Посмотрел, еще так же нашел — www.acooke.org/lepl/
Нужно будет посмотреть как описание грамматики будет выглядеть — насколько громоздко, а так вариант :)
Если бы небыло строк которые могут содержать пробелы «Mary Rose Jesus» — это тоже name и surname — то можно было конечно, ибо тут можно красиво сделать типа
(a, b, c, d) = [t(s) for t,s in zip((int,float,bool,str),data.split())]
Но увы, хочет чтобы строка была именно сторой. Да и плюс как проверять то что сматчилось верно? Писать дикое услови split_result[5] == "/"?
Но в целом что-то такое подойдет, все свое — легче контролировать если что… Только открытый вопрос что делать со сложными типа данных — типа float или datetime.
Для float он из примера можно взять — ""([-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?)" — но жесть же :)
Да и с int проблема — такой вариант если в строке будет 0xAB уже не подойдет — в моем конкретно случае это не нужно… Но как бы потом не забыть, а то маленькие утилитки разрастаться имеют тенденцию :)