Python re.sub - Заменить число определенной длины в строке с другими числами

Нужно в строке заменить число определенной длины на символы {} для будущей вставки переменной. Строка может быть такой "asd11234qerty1ghj" или например такой "asd11234qerty001ghj" В первом случае нужно найти "1", во втором "001". Сам паттерн и его длина известны - искать \d+ не обязательно, хотя желательно для универсальности кода, но в raw-строку переменную не вставишь. Конструкция такого вида (c двойными {{}}):

PATTERN = "\D(\d{{}})\D".format(str(LEN))

ломает логику и f-строкам, и методу format:

LEN = 1
#PATTERN = f"\D(\d{{LEN}})\D"
PATTERN = "\D(\d{{}})\D".format(str(LEN))
sub(PATTERN, r'{}', 'asd11234qerty1ghj')

А поиск непосредственно по известному паттерну заменит либо все единицы:

PATTERN = '1'
sub(PATTERN, r'{}', 'asd11234qerty1ghj')

либо и соседние символы, если так:

PATTERN = f'\D{PATTERN}\D'
sub(PATTERN, r'{}', 'asd11234qerty1ghj')

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


Ответы (1 шт):

Автор решения: Stanislav Volodarskiy

Чтобы в форматную строку вставить фигурные скобки, их надо удвоить.
Не-цифры до и после образца закрываем в условные выражения (lookbehind и lookahead).

LEN = 1
PATTERN = rf'(?<=\D)\d{{{LEN}}}(?=\D)'
print(re.sub(PATTERN, '{}', 'asd11234qerty1ghj'))

Ещё один вариант. Здесь по другому записано требование к не-цифрам вокруг числа. Это выражение умеет обрабатывать числа в начале и конце строки:

LEN = 1
PATTERN = rf'(?<!\d)\d{{{LEN}}}(?!\d)'
print(PATTERN)
→ Ссылка