Дефис внутри наборов в регулярках Python
Дефис - тоже спецсимвол внутри [ ]
(а вот снаружи - нет). Если вам нужен сам
дефис как символ - то поставьте его там,
где он не будет воспринят как разделитель
группы.
Почему это важно: вы можете сделать группу
символов, сами не заметив этого. К примеру,
вот так - '[:-@]'
- вы думаете, что
выбираете двоеточие, дефис и собаку, а на
самом деле получается группа символов между
:
и @
. В эту группу входят
следующие символы: ? = > :
Откуда они взялись? Из таблицы ASCII - двоеточие имеет номер меньше, чем собака - и получается группа. То есть все группы получаются по таблице ASCII (при желании этим можно пользоваться).
Как с этим бороться: поставьте символ дефиса
там, где он точно не будет воспринят как
символ группы, например, в начале или в конце
(то есть после [
или перед ]
).
Можно также заэкранировать дефис - тогда
он будет обозначать сам себя независимо от
позиции. Например, вместо [:-@]
написать
[:\-@]
- и группы уже не будет, а
будут три символа - двоеточие, дефис и собака
@
.
Пример
В следующем примере шаблон поиска такой:
цифра 1
, затем буква от 'a'
до 'z'
, затем цифра 2
:
txt = '1a2 1-2 1c2 1z2'
res = re.sub('1[a-z]2', '!', txt)
print(res)
Результат выполнения кода:
'! 1-2 ! !'
Пример
Давайте теперь заэкранируем дефис. В результате
шаблон поиска такой: цифра 1
, затем
буква 'a'
, или дефис, или буква 'z'
,
затем цифра 2
:
txt = '1a2 1-2 1c2 1z2'
res = re.sub('1[a\-z]2', '!', txt)
print(res)
Результат выполнения кода:
'! ! 1c2 !'
Пример
Можно просто переставить дефис, не экранируя его:
txt = '1a2 1-2 1c2 1z2'
res = re.sub('1[az-]2', '!', txt)
print(res)
Результат выполнения кода:
'! ! 1c2 !'
Пример
В следующем примере шаблон поиска такой:
первый символ - это маленькие буквы или
дефис '-'
, потом две буквы
'x'
:
txt = 'axx Axx -xx @xx'
res = re.sub('[a-z-]xx', '!', txt)
print(res)
Результат выполнения кода:
'! Axx ! @xx'
Пример
В следующем примере шаблон поиска такой:
первый символ - это маленькие, большие
буквы или дефис '-'
, потом две буквы
'x'
:
txt = 'axx Axx -xx @xx'
res = re.sub('[a-zA-Z-]xx', '!', txt)
print(res)
Результат выполнения кода:
'! ! ! @xx'
Пример
Можно расположить дефис между двумя группами - там он точно еще не сделает еще одну группу:
txt = 'axx 9xx -xx @xx'
res = re.sub('[a-z-0-9]xx', '!', txt)
print(res)
Результат выполнения кода:
'! ! ! @xx'
Практические задачи
Дана строка:
txt = 'xaz xBz xcz x-z x@z'
Найдите все строки по следующему шаблону:
буква 'x'
, большая или маленькая
буква или дефис, буква 'z'
.
Дана строка:
txt = 'xaz x$z x-z xcz x+z x%z x*z'
Найдите все строки по следующему шаблону:
буква 'x'
, затем или доллар, или
дефис или плюс, потом буква
'z'
.