Замена одинаковых последовательностей символов в строке на регулярное выражение в jinja2 или python - PullRequest
0 голосов
/ 01 сентября 2018

На всю жизнь я не могу понять, как получить регулярное выражение, которое заменяет все одинаковые повторяющиеся символы в строке числом, соответствующим количеству повторений, плюс повторяющийся символ для каждого экземпляра.

Например, допустим, у меня есть эта строка на входе: "НВ ??? Б ??? ??? Б Б Б ??? ??? ??? Б Б Б ??? ???" * * +1003

Я хочу получить следующий шаблон в выводе: "HB3? B3? B3? B3? B3? B3? B3? B3?"

Я задаю этот вопрос, потому что я использую jinja2 для создания python шаблонов. Эти файлы Python используют стандартный модуль struct , и мне нужно автоматически генерировать вероятные огромные структуры на основе спецификации. Мне нужно распаковать все сразу, потому что выравнивание байтов при распаковке отдельных данных вызывает проблемы на некоторых архитектурах процессора, которые я использую.

Может быть, есть лучшее решение, о котором я не думал.

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

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

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

Математически это не обычный язык, и выражение для сопоставления с ним не является также регулярным выражением, но оно работает, как это было реализовано в ранних версиях unix.

HB(...)\1*

Здесь, группа из двух символов карты (любые, кроме новой строки) '.' сопоставляется, и тогда к нему может быть присоединена любая последовательность 0 или более (согласно оператору *). Это будет соответствовать таким вещам, как

HBABCABCABCABCABCABC

или

HBBBABBABBABBABBA

но не

HBBBABBABBABB  (not complete the sequence of three letters BBA)

См. демо

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

0 голосов
/ 01 сентября 2018

Вот решение с использованием python re.sub

>>> import re
>>> s = "HB???B???B???B???B???B???B???B???"
>>> re.sub(r'\?+', lambda m: str(len(m.group()))+'?', s)
'HB3?B3?B3?B3?B3?B3?B3?B3?'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...