Можно объединить весь regexes в одно использование "|" оператор и позволить regex библиотеке сделать работу различения между маркерами. Некоторую заботу нужно соблюдать для обеспечения предпочтения маркеров (например, чтобы не соответствовать ключевому слову как идентификатору).
re.match
привязывается. Можно дать ему аргумент положения:
pos = 0
end = len(text)
while pos < end:
match = regexp.match(text, pos)
# do something with your match
pos = match.end()
Взглянули для пигментов, который поставляет shitload лексических анализаторов в целях подсветки синтаксиса с различными реализациями, большинством на основе регулярных выражений.
Возможно, что объединение маркера regexes будет работать, но необходимо было бы сравнить его. Что-то как:
x = re.compile('(?P<NUMBER>[0-9]+)|(?P<VAR>[a-z]+)')
a = x.match('9999').groupdict() # => {'VAR': None, 'NUMBER': '9999'}
if a:
token = [a for a in a.items() if a[1] != None][0]
фильтр - то, где необходимо будет сделать некоторое сравнительное тестирование...
Обновление: я протестировал это, и кажется как будто, если Вы комбинируете все маркеры, как указано и пишете функцию как:
def find_token(lst):
for tok in lst:
if tok[1] != None: return tok
raise Exception
Вы получите примерно ту же скорость (возможно, крохотное быстрее) для этого. Я полагаю, что ускорение должно быть в количестве вызовов для соответствия, но цикл для маркерной дискриминации все еще там, который, конечно, уничтожает его.
Это не точно прямой ответ на Ваш вопрос, но Вы могли бы хотеть посмотреть ANTLR. Согласно этот документируют цель генерации кода Python, должно быть актуальным.
относительно Вашего regexes, существует действительно два способа пойти об ускорении его, если Вы придерживаетесь regexes. Первое должно было бы заказать Ваш regexes в порядке вероятности нахождения их в тексте по умолчанию. Вы могли изобразить добавление простого профилировщика к коду, который собранный маркер значит каждый тип маркера и выполнение лексического анализатора на собрании произведений. Другим решением был бы к блочной сортировке Ваш regexes (так как Ваше ключевое пространство, будучи символом, является относительно небольшим), и затем используйте массив или словарь для выполнения необходимого regexes после выполнения единственной дискриминации на первом символе.
Однако я думаю, что, если Вы собираетесь пойти этим путем, необходимо действительно попробовать что-то как ANTLR, который будет легче поддержать, быстрее, и менее вероятно иметь ошибки.