Ограничаване на алчността в регулярните изрази в Python
Регулярните изрази по подразбиране са алчни. Това означава, че те захващат максимално възможното количество символи. Нека разгледаме пример. Да предположим, че имаме следния низ:
txt = 'aeeex zzz x kkk'
В този низ искаме да намерим подниза
'aeeex' със следния шаблон:
буква 'a', последвана от произволен символ
един или повече пъти, последвана от буква 'x':
res = re.sub('a.+x', '!', txt)
print(res)
Въпреки че очакваме да получим низ '! zzz
x kkk', ще се изведе низ '! kkk'.
Цялата работа е в това, че нашето регулярно изразяване търси
всички символи от буквата 'a' до буквата
'x'. Но в нашия низ има две букви
'x'! Поради алчността се оказва, че
регулярният израз търси до последната буква 'x',
като по този начин захваща не това, което ни
трябваше.
Разбира се, често това поведение е точно това, което ни трябва. Но конкретно в този случай трябва да деактивираме алчността и да кажем на регулярния израз, да търси до първата буква 'x'. В този случай след оператора за повторение трябва да поставим въпросителен знак:
res = re.sub('a.+?x', '!', txt)
print(res) # ще изведе низа '! zzz x kkk'
Алчността може да бъде ограничена за всички оператори
за повторение: както *, така и ?, и
{} - ето така: *?, ??
и {}?.
Даден е низ:
txt = 'aba accca azzza wwwwa'
Напишете регулярен израз, който ще намери всички
низове, в които от двете страни има букви
'a', и ще замени всеки от тях с
'!'. Между буквите 'a' може
да има произволен символ (освен 'a').