Я ищу что-то похожее на механизм регулярных выражений, но позволяет полностью перекрывать результаты и позволяет манипулировать внутренним «курсором», когда движок возвращает совпадения ,Регулярно/совпадающий движок с полностью перекрывающимися результатами и манипуляцией «курсором»
нормальный регулярное выражение так:
Скажем, у вас нормальное регулярное выражение с различными «альтернатив»: item1|item2|item3
, и вы используете либо findall
или finditer
, чтобы получить все матчи. В определенной позиции во входной строке двигатель может соответствовать любым из этих альтернатив. После обнаружения курсор продвигается к индексу сразу после окончания матча и продолжает искать любую альтернативу. Даже если два или более из этих альтернатив, возможно, соответствуют строке в позиции начального курсора, только один возвращаются:
import re
input_string = 'foobar'
compiled = re.compile('foobar|foo|bar')
compiled.findall(input_string)
# 'foobar'
То, что я хочу (1):
Я хочу, чтобы они все были вернулся. Как так:
import muchneededregexthing
input_string = 'foobar'
compiled = muchneededregexthing.compile('foobar|foo|bar')
searcher = compiled.create_searcher(input_string)
while not searcher.reached_end():
match = searcher.search() # increments searcher's internal cursor
# to after the end of the match
print(match.string, match.span())
# foobar (0,6)
# foo (0,3)
# bar (3,6)
То, что я также хочу (2):
Я хочу, чтобы иметь возможность изменить курсор искателя, так что я могу манипулировать результатами в соответствии с тем, что происходит во время выполнения (» foobar ', и «foo» и «bar» отдельно не имеют значения).
import muchneededregexthing
input_string = 'foobarkitten'
compiled = muchneededregexthing.compile('foobar|foo|bar|kitten')
searcher = compiled.create_searcher(input_string)
while not searcher.reached_end():
match = searcher.search() # increments searcher's internal cursor
# to after the end of the match
print(match.string, match.span())
if match.string == 'foobar':
searcher.advance_cursor(match.end())
# foobar (0,6)
# kitten (6,12)
То, что я не могу использовать (скорее всего):
str.find
: Мне нужно регулярное выражение вещь для разметки (уценки/вики/и т.д.) парсера. В любое время, возможно, придется искать много разных элементов. Использованиеstr.find
Мне нужно будет искать весь документ с каждым элементом, который поддерживает разметка. Язык слишком сложный, чтобы разделить документ на куски, такие как «кусок заголовка», «параграф абзаца» и т. Д.: Если я не могу поддержать то, что мне нужно, я не могу использовать его по следующей причине: regexes ограничены, вы не можете подобрать что угодно. Однако их свойства полезны для таких случаев, как мой. Я планирую совпадение в два этапа: регулярное выражение обеспечивает возможное соответствие элемента. Затем следует использовать умную функцию/метод, соответствует ли совпадению . Если да, то большой, продвигаемый курсор. Если нет, завинтите
foobar
и дайтеfoo
иbar
шанс самостоятельно.
Идеи приветствуются. Я абсолютно уверен, что мне нужны указанные функции. Моя лучшая идея заключается в том, чтобы написать собственный модуль muchneededregexthing
с поддержкой большей части синтаксиса регулярных выражений на C/C++, поэтому не бойтесь, что я буду игнорировать вашу идею как надуманную.
Редактировать 1: запрос пример разметки:
элементов разметки, и поэтому маркеры, которые должны быть согласованы, определены и приведены в с помощью плагинов.Поэтому структура не содержит никакой разметки. Я мог бы просто сопоставить токен плагина с регулярным выражением и сделать с ним, но я хочу, по крайней мере, изучить параметры и попытаться разрешить большее количество маркеров разметки, чем то, что можно было бы поддерживать с помощью регулярного выражения. Например, как бы соответствовать string:number
, если бы их отношение состояло в том, что число должно быть числом численного представления строки? a:0
- действительный токен, но a:1
нет. b:1
есть, однако, и поэтому bc:28
(1 * 26 + 2 * 1).
В этом примере плагин может содержать регулярное выражение, такое как ([a-z]{1,5})([0-9]{1,5})
. Затем алгоритм передает соответствие специальной функции, которая вычисляет численное значение первой группы и сравнивает ее со значением второй группы. Если эти значения совпадают, то плагин будет обрабатывать эту часть документа. Если нет, он возвращается и делается попытка сделать другой плагин обработчиком этого индекса в документе.
Поведение по умолчанию совпадающего соответствия - это перемещение курсора по одной позиции после каждого совпадения. Если не разрешено продвигать хотя бы одну позицию, она вводит бесконечный цикл. Регулярное выражение исправлено. Пример '(? = (O + | foo))' в строке 'fooooo' находит 5 совпадений. Кроме того, один символ существует в позиции за раз, поэтому только регулярное выражение может быть переменным. То есть. _item_'X' может быть только _X_ и никогда Y. Но регулярное выражение фиксируется в состоянии, поэтому оно никогда не может меняться. Таким образом, продвижение позиции. – sln
Вы могли бы использовать несколько регулярных выражений, чтобы отсканировать одну позицию. Но вы должны контролировать это, установив регулярное выражение и установив позицию в строке. Это одно действие. – sln
Можете ли вы привести пример своей уценки? Вероятно, это можно решить с помощью регулярного выражения или рекурсивного синтаксического анализатора. – fafl