Моя задача - преобразовать «исходный» текст в последовательность элементов: TEXT
и INPUT
. INPUT
- это те части, которые обернуты в две звездочки, а TEXT - все остальное.
Вот пример:
>>> source = 'I came *across* these old photos when I *was* tidying the closet.'
>>> parse(source)
TEXT: 'I came '
INPUT: 'across'
TEXT: ' these old photos when I '
INPUT: 'was'
TEXT: ' tidying the closet.'
Цель такого анализа - создать «заполнение»интерактивный инструмент для языковой подготовки. Проанализированные элементы в конечном итоге перейдут на клиентскую сторону, где элементы TEXT
отображаются «как есть», а элементы INPUT
отображаются как поля ввода для ввода пользователем.
Для этого янемного изменили пример, приведенный в Запись токенизатора в документации библиотеки re
. Вот мое решение:
def parse(text):
token_specifications = [
('INPUT', r'(\*\w\*)|(\*\w+[^*]*\w+\*)'),
('TEXT', r'[^*]+'),
]
token_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specifications)
elements = []
for mo in re.finditer(token_regex, text):
kind = mo.lastgroup
value = mo.group()
# A hack to remove the delimiters
if kind == 'INPUT':
value = value.replace('*', '')
print("%s: '%s'" % (kind, value))
elements.append((kind, value))
# Testing the result
if elements != [
('INPUT', 'This'),
('TEXT', ' is '),
('INPUT', 'a'),
('TEXT', ' text that '),
('INPUT', 'needs to be'),
('TEXT', ' parsed. '),
('INPUT', 'Highlighted'),
('TEXT', ' elements must be in '),
('INPUT', 'INPUT'),
('TEXT', ' group.'),
]:
raise Exception("Parsing result is wrong!")
text = '*This* is *a* text that *needs to be* parsed. *Highlighted* elements must be in *INPUT* group.'
parse(text)
Это работает, как и ожидалось, и выглядит достаточно аккуратно, за исключением одной небольшой проблемы. А именно, элементы INPUT
поставляются вместе со звездочками, и я должен явно удалить их (см. A hack to remove the delimiters
часть кода).
Есть ли способ заставить функцию finditer()
выдавать разделителипрочь, так что мне не нужно делать это явно?
Кроме того, если есть какие-либо другие советы, чтобы сделать мой код более элегантным, они более чем приветствуются.