Экранировка спецсимволов в регулярках Python
Предположим, что нужно сделать так, чтобы спецсимвол обозначал сам себя. Для этого его следует экранировать с помощью обратного слеша. Давайте посмотрим на примерах.
Пример
В следующем примере автор регулярки хотел,
чтобы шаблон поиска выглядел так: буква
'a'
, затем плюс '+'
, затем
буква 'x'
. Однако, автор кода
не заэкранировал символ '+'
и поэтому
шаблон поиска самом деле он выглядит так:
буква 'a'
один или более раз,
потом буква 'x'
:
txt = 'a+x ax aax aaax'
res = re.sub('a+x', '!', txt)
print(res)
Результат выполнения кода:
'a+x ! ! !'
Пример
А сейчас автор заэкранировал плюс обратным
слешем. Теперь шаблон поиска выглядит так,
как надо: буква 'a'
, затем плюс
'+'
, затем буква 'x'
:
txt = 'a+x ax aax aaax'
res = re.sub('a\+x', '!', txt)
print(res)
Результат выполнения кода:
'! ax aax aaax'
Пример
В данном примере шаблон выглядит так:
буква 'a'
, затем точка '.'
,
затем буква 'x'
:
txt = 'a.x abx azx'
res = re.sub('a\.x', '!', txt)
print(res)
Результат выполнения кода:
'! abx azx'
Пример
А следующем примере автор забыл заэкранировать слеш и под регулярку попали все подстроки, так как незаэкранированная точка обозначает любой символ:
txt = 'a.x abx azx'
res = re.sub('a.x', '!', txt)
print(res)
Результат выполнения кода:
'! ! !'
Замечание
Обратите внимание на то, что если вы забудете обратный слеш для точки (когда она должна обозначать сама себя) - этого можно даже не заметить:
res = re.sub('a.x', '!', 'a.x')
print(res) # вернет '!', как мы и хотели
Визуально работает правильно (так как точка
обозначает любой символ, в том числе и
обычную точку '.'
). Но если поменять
строку, в которой происходят замены - мы
увидим нашу ошибку:
res = re.sub('a.x', '!', 'a.x abx azx')
print(res) # вернет '! ! !', а ожидалось '! abx azx'
Список специальных символов и обычных
Если экранировать обычный символ - ничего страшного не случится - он все равно будет обозначать сам себя. Исключение - цифры, их нельзя экранировать.
Часто возникает сомнение, является ли данный символ специальным. Некоторые доходят до того, что экранируют все подозрительные символы подряд. Однако, это плохая практика (захламляет регулярку обратными слешами).
Являются спецсимволами: $ ^ . * + ? \ / {} [] () |
Не являются спецсимволами: @ : , ' " - _ = < > % # ~ `& !
Практические задачи
Дана строка:
txt = 'a.a aba aea'
Напишите регулярку, которая найдет строку
'a.a'
, не захватив остальные.
Дана строка:
txt = '2+3 223 2223'
Напишите регулярку, которая найдет строку
'2+3'
, не захватив остальные.
Дана строка:
txt = '23 2+3 2++3 2+++3 345 567'
Напишите регулярку, которая найдет строки
'2+3'
, '2++3'
, '2+++3'
,
не захватив остальные (+ может быть любое
количество).
Дана строка:
txt = '23 2+3 2++3 2+++3 445 677'
Напишите регулярку, которая найдет строки
'23'
, '2+3'
, '2++3'
,
'2+++3'
, не захватив остальные.
Дана строка:
txt = '*+ *q+ *qq+ *qqq+ *qqq qqq+'
Напишите регулярку, которая найдет строки
'*q+'
, '*qq+'
, '*qqq+'
,
не захватив остальные.
Дана строка:
txt = '[abc] {abc} abc (abc) [abc]'
Напишите регулярку, которая найдет строки
в квадратных скобках и заменит их на
'!'
.