Я пишу правила лексера для пользовательского языка описания, используя pyLR1 , который должен включать литералы времени, такие как, например,:
10h30m # meaning 10 hours + 30 minutes
5m30s # meaning 5 minutes + 30 seconds
10h20m15s # meaning 10 hours + 20 minutes + 15 seconds
15.6s # meaning 15.6 seconds
Порядок указания частей часа, минут и секунд должен быть установлен h
, m
, s
. Чтобы указать это подробно, мне нужны следующие допустимые комбинации hms
, hm
, h
, ms
, m
иs
(с номерами между различными сегментами, конечно ). В качестве бонуса регулярное выражение должно проверять десятичные (, т. е. не -натуральные )числа в сегментах, и разрешать их только в сегменте с наименьшей значимостью.
Итак, у меня есть для всех, кроме последней группы, совпадение числа, например:
([0-9]+)
А для последней группы даже:
([0-9]*\.[0-9]+|[0-9]+(\.[0-9]*)?) # to allow for.5 and 0.5 and 5.0 and 5
Перебирая все комбинации h, m и s, симпатичный маленький скрипт на Python дает мне следующее регулярное выражение:
(([0-9]*\.[0-9]+|[0-9]+(\.[0-9]*)?)h|([0-9]+)h([0-9]*\.[0-9]+|[0-9]+(\.[0-9]*)?)m|([0-9]+)h([0-9]+)m([0-9]*\.[0-9]+|[0-9]+(\.[0-9]*)?)s|([0-9]*\.[0-9]+|[0-9]+(\.[0-9]*)?)m|([0-9]+)m([0-9]*\.[0-9]+|[0-9]+(\.[0-9]*)?)s|([0-9]*\.[0-9]+|[0-9]+(\.[0-9]*)?)s)
Очевидно, это немного выражение ужаса. Есть ли способ упростить это? Ответ должен работать с модулем pythons re
, и я также приму ответы, которые не работают с pyLR1
, если это связано с его ограниченным подмножеством регулярных выражений.