Эффективно соответствуйте нескольким regexes в Python

14
задан Rafał Dowgird 6 April 2016 в 12:49
поделиться

4 ответа

Можно объединить весь regexes в одно использование "|" оператор и позволить regex библиотеке сделать работу различения между маркерами. Некоторую заботу нужно соблюдать для обеспечения предпочтения маркеров (например, чтобы не соответствовать ключевому слову как идентификатору).

7
ответ дан 1 December 2019 в 08:44
поделиться

re.match привязывается. Можно дать ему аргумент положения:

pos = 0
end = len(text)
while pos < end:
    match = regexp.match(text, pos)
    # do something with your match
    pos = match.end()

Взглянули для пигментов, который поставляет shitload лексических анализаторов в целях подсветки синтаксиса с различными реализациями, большинством на основе регулярных выражений.

3
ответ дан 1 December 2019 в 08:44
поделиться

Возможно, что объединение маркера 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

Вы получите примерно ту же скорость (возможно, крохотное быстрее) для этого. Я полагаю, что ускорение должно быть в количестве вызовов для соответствия, но цикл для маркерной дискриминации все еще там, который, конечно, уничтожает его.

3
ответ дан 1 December 2019 в 08:44
поделиться

Это не точно прямой ответ на Ваш вопрос, но Вы могли бы хотеть посмотреть ANTLR. Согласно этот документируют цель генерации кода Python, должно быть актуальным.

относительно Вашего regexes, существует действительно два способа пойти об ускорении его, если Вы придерживаетесь regexes. Первое должно было бы заказать Ваш regexes в порядке вероятности нахождения их в тексте по умолчанию. Вы могли изобразить добавление простого профилировщика к коду, который собранный маркер значит каждый тип маркера и выполнение лексического анализатора на собрании произведений. Другим решением был бы к блочной сортировке Ваш regexes (так как Ваше ключевое пространство, будучи символом, является относительно небольшим), и затем используйте массив или словарь для выполнения необходимого regexes после выполнения единственной дискриминации на первом символе.

Однако я думаю, что, если Вы собираетесь пойти этим путем, необходимо действительно попробовать что-то как ANTLR, который будет легче поддержать, быстрее, и менее вероятно иметь ошибки.

1
ответ дан 1 December 2019 в 08:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: