Экранироўка спецсімвалаў у рэгулярках Python

Выкажам здагадку, што трэба зрабіць так, каб спецсімвал абазначаў сам сябе. Для гэтага яго варта экранаваць з дапамогай адваротнага слешу. Давайце паглядзім на прыкладах.

Прыклад

У наступным прыкладзе аўтар рэгуляркі хацеў, каб шаблон пошуку выглядаў так: літара 'a', потым плюс '+', потым літара 'x'. Аднак, аўтар кода не заэкранаваў сімвал '+' і таму шаблон пошуку на самой справе ён выглядае так: літара 'a' адзін ці больш разоў, потым літара 'x':

pythontxt = 'a+x ax aax aaax'
res = re.sub('a+x', '!', txt)

print(res)

Вынік выканання кода:

python'a+x ! ! !'

Прыклад

А зараз аўтар заэкранаваў плюс адваротным слешам. Цяпер шаблон пошуку выглядае так, як трэба: літара 'a', потым плюс '+', потым літара 'x':

pythontxt = 'a+x ax aax aaax'
res = re.sub('a\+x', '!', txt)

print(res)

Вынік выканання кода:

python'! ax aax aaax'

Прыклад

У гэтым прыкладзе шаблон выглядае так: літара 'a', потым кропка '.', потым літара 'x':

pythontxt = 'a.x abx azx'
res = re.sub('a\.x', '!', txt)

print(res)

Вынік выканання кода:

python'! abx azx'

Прыклад

У наступным прыкладзе аўтар забыўся заэкранаваць слеш і пад рэгулярку трапілі ўсе падрадкі, бо неэкранаваная кропка абазначае любы сімвал:

pythontxt = 'a.x abx azx'
res = re.sub('a.x', '!', txt)

print(res)

Вынік выканання кода:

python'! ! !'

Заўвага

Звярніце ўвагу на тое, што калі вы забудзецеся адваротны слеш для кропкі (калі яна павінна абазначаць саму сябе) – гэтага можна нават не заўважыць:

pythonres = re.sub('a.x', '!', 'a.x')
print(res) # верне '!', як мы і хацелі

Візуальна працуе правільна (бо кропка абазначае любы сімвал, у тым ліку і звычайную кропку '.'). Але калі змяніць радок, у якім адбываюцца замены – мы ўбачым нашу памылку:

pythonres = re.sub('a.x', '!', 'a.x abx azx')
print(res) # верне '! ! !', а чакалася '! abx azx'

Спіс спецыяльных сімвалаў і звычайных

Калі экранаваць звычайны сімвал – нічога дрэннага не здарыцца – ён усё роўна будзе абазначаць сам сябе. Выключэнне – лічбы, іх нельга экранаваць.

Часта ўзнікае сумненне, ці з'яўляецца гэты сімвал спецыяльным. Некаторыя даходзяць да таго, што экрануюць усе падазроныя сімвалы падряд. Аднак, гэта дрэнная практыка (засмічвае рэгулярку адваротнымі слешамі).

З'яўляюцца спецсімваламі: $ ^ . * + ? \ / {} [] () |

Не з'яўляюцца спецсімваламі: @ : , ' " - _ = < > % # ~ `& !

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

Задание 1

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

pythontxt = 'a.a aba aea'

Напішыце рэгулярку, якая знойдзе радок 'a.a', не захапіўшы астатнія.

Задание 2

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

pythontxt = '2+3 223 2223'

Напішыце рэгулярку, якая знойдзе радок '2+3', не захапіўшы астатнія.

Задание 3

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

pythontxt = '23 2+3 2++3 2+++3 345 567'

Напішыце рэгулярку, якая знойдзе радкі '2+3', '2++3', '2+++3', не захапіўшы астатнія (+ можа быць любая колькасць).

Задание 4

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

pythontxt = '23 2+3 2++3 2+++3 445 677'

Напішыце рэгулярку, якая знойдзе радкі '23', '2+3', '2++3', '2+++3', не захапіўшы астатнія.

Задание 5

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

pythontxt = '*+ *q+ *qq+ *qqq+ *qqq qqq+'

Напішыце рэгулярку, якая знойдзе радкі '*q+', '*qq+', '*qqq+', не захапіўшы астатнія.

Задание 6

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

pythontxt = '[abc] {abc} abc (abc) [abc]'

Напішыце рэгулярку, якая знойдзе радкі у квадратных дужках і замяніць іх на '!'.