Пазітыўны і негатыўны прагляд у рэгулярках Python

Часам трэба вырашыць задачу такога тыпу: знайсці радок 'aaa' і замяніць яе на '!', але толькі калі пасля 'aaa' стаіць 'x', а сам 'x' пры гэтым не замяняць. Калі мы паспрабуем вырашыць задачу 'ў лоб', то ў нас нічога не выйдзе:

pythontxt = 'aaax baaa'
res = re.sub('aaax', '!', txt)

print(res) # выведзе '! baaa', а хацелі '!x baaa'

Прагляд наперад

Для вырашэння задачы патрэбны спосаб сказаць, што 'x' не варта замяняць. Робіцца гэта з дапамогай спецыяльных дужак (?= ), якія проста глядзяць, але не забіраюць з сабой.

Гэтыя дужкі называюцца пазітыўны прагляд наперад. Пазітыўны - так як 'x' (у нашым выпадку) павінен быць - толькі тады адбудзецца замена.

Давайце прымянім гэтыя дужкі для вырашэння нашай задачы:

pythontxt = 'aaax baaa'
res = re.sub('aaa(?=x)', '!', txt)
print(res) # выведзе '!x aaab

Ёсць і негатыўны прагляд наперад - (?! ) - ён, насупраць, кажа, што чагосьці павінна не быць. У наступным прыкладзе, замена адбудзецца, толькі калі пасля 'aaa' стаіць НЕ 'x':

pythontxt = 'aaax aaab'
res = re.sub('aaa(?!x)', '!', txt)

print(res) # выведзе 'aaax !b'

Прагляд назад

Аналагічным чынам ёсць пазітыўны прагляд назад - (?<= ). У наступным прыкладзе замена адбудзецца, толькі калі перад 'aaa' стаіць 'x':

pythontxt = 'xaaa'
res = re.sub('(?<=x)aaa', '!', txt)

print(res) # выведзе 'x!'

І ёсць таксама негатыўны прагляд назад - (?<! ). У наступным прыкладзе замена адбудзецца, толькі калі перад 'aaa' не стаіць 'x':

pythontxt = 'baaa'
res = re.sub('(?<!x)aaa', '!', txt)

print(res) # выведзе 'b!'

Практычныя задачы

Задание 1

Дадзены радок, які змяшчае імёны функцый:

pythontxt = 'func1() func2() func3()'

Атрымайце масіў імёнаў функцый з радка.

Задание 2

Дадзены радок з тэгам:

pythontxt = '<a href="" class="eee" id="zzz">'

Атрымайце масіў імёнаў атрыбутаў гэтага тэга.

Задание 3

Дадзены радок з зменнымі:

pythontxt = '$aaa $bbb $ccc xxxx'

Атрымайце падрадкі, перад якімі стаіць сімвал долара.