Метод find ищет подстроку в строке.
s='абракадабра'
s.find('бра')
Если подстрока не найдена, он возвращает -1.
s.find('бро')
Можно задать дополнительный параметр - начиная с какого места искать.
s.find('бра',3)
Метод replace возвращает копию строки, в кторой старая подстрока заменена на новую.
s.replace('бра','БРА')
Если задать дополнительный целый параметр n, то будут заменены только первые n вхождений старой подстроки.
s.replace('бра','БРА',1)
Но эти методы работают только с фиксированными подстроками. Для более гибкой обработки текстов можно использовать модуль re, который позволяет искать и заменять подстроки, соответствующий некоторым образцам - регулярным выражениям.
from re import search,sub,compile
Функция search(r,s) ищет подстроку, соответствующую регулярному выражению r, в строке s. Она возвращает объект сопоставления или None, если такая подстрока не найдена. Из объекта сопоставления можно добыть полезную информацию о том, как регулярное выражение сопоставлено подстроке.
s='xy xay xaby xby'
m=search('x.y',s)
if m:
print(m.start(),m.end(),m.group())
else:
print('Не найдено')
Самая часто используемая функция того модуля - это sub. Она возвращает копию исходной строки, в которой все подстроки, соответствующие образцу, заменены на заданную строку - замену.
sub('x.y','XXX',s)
Если мы хотим заменить только первые n подстрок, соответствующих образцу, добавляем параметр n.
sub('x.y','XXX',s,1)
Если мы хотим использовать одно и то же регулярное выражение несколько раз, можно скомпилировать его в некий объект, и вместо функций модуля re вызывать методы этого объекта. Это повысит эффективность.
xy=compile('x.y')
m=xy.search(s)
print(m.group())
xy.sub('XXX',s)
В регулярном выражении все символы, кроме специальных, обозначают сами себя. Специальные символы - это ., ^, $, *, +, ?, \, |, {, }, [, ], (, ). Если требуется включить в регулярное выражение один из этих символов буквально, как обычный, перед ним нужно поставить \. Вообще, в регулярных выражениях часто приходится использовать \. А чтобы включить этот символ в строку на питоне, его надо писать как \\. Например, регулярное выражение, которое сопоставляется с символом \ - это \\; в виде питонской строки его приходится писать как '\\\\'. Неудобно. Поэтому для записи регулярных выражений часто используют сырые строки (raw, в смысле неприготовленные - не варёные и не жареные). Они пишутся как r'строка' или r"строка", в них \ является вполне обычным символом. Так что это же регулярное выражение можно записать в виде сырой строки r'\\'.
r'\n'
Специальный символ . в регулярном выражении сопоставляется с любым (одним!) символом в строке (кроме символа '\n'). Мы это уже видели. Конструкция [abc] сопоставляется с a, b или c. В ней можно использовать диапазоны: [0-9] - это любая цифра, а [a-zA-Z] - любая латинская буква. Но тут надо быть осторожным: это диапазоны в юникоднм порядке. Латинские буквы в нём действительно идут подряд, так что для обычных латинских букв (без каких-нибудь умляютов) это правильно. Но вот [а-яА-Я] не включает все расские буквы - ё и Ё находятся вне этих диапазонов. Большинство специальных символов теряют свою специальность между [ и ] и рассматриваются как обычные. Если первым символом после [ идёт ^, то это значит любой символ, кроме тех, что дальше перечислены.
Юникод умеет много гитик, поэтому надёжнее использовать заранее определённые классы символов. Так, \d означает любую цифру (в юникоде, в добавок к [0-9], их есть ещё много); \w означает любой символ, который может присутствовать в слове - букву, цифру или _; \s означает любой "пробел" (пустое пространство, включая табуляцию, '\n' и т.д.). Заглавные буквы означают дополнения к этим множествам: \D - любая не-цифра; \W - не встречается в словах (т.е. не буква, не цифра и не _); \S - любой не-пробел.
После подвыражения в регулярном выражении можно поставить *, это означает любое число повторений (от 0 до $\infty$) этого подвыражения. Например, .* сопоставляется с абсолютно чем угодно. Если поставить +, то это любое ненулевое число повторений (от 1 до $\infty$). А если поставить ?, то это 0 или 1 вхождение, т.е. это предыдущее подвыражение может присутствовать либо отсутствовать. Можно задать возможные числа повторений более явно: а{5} означает 5 букв а, а{2,4} - от 2 до 4 букв а, а{6,} - от 6 до $\infty$ букв а. Но это используется редко.
m=search(r'\d+','abc123xyz')
print(m.group())
^ означает начало строки, а $ - конец.
for s in ['0ab','a0b']:
if search(r'^0',s):
print('нашли')
else:
print('не нашли')
x|y означает x или y. Подвыражения можно заключать в скобки.
m=search(r'(a\d+b)|(c\d+d)','xxxc123dyyy')
print(m.group())
m=search(r'0(ab)*1','x0ababab1y')
print(m.group())
Но главная польза от скобок не в этом. Каждая скобка создаёт группу. При поиске регулярного выражения в строке куски строки, сопоставленные каждому подвыражению в скобках, запоминаются, и их можно извлечь и использовать. Метод group объекта сопоставления, вызванный без параметров, возвращает подстроку, сопоставленную всему регулярному выражению в целом; если же его вызвать с целым параметром n, то он возвращает n-ую группу.
m=search(r'(^[a-z]*)(\d*)([a-z]*$)','abc123xyz')
print(f'1: {m.group(1)}, 2: {m.group(2)}, 3: {m.group(3)}')
Ещё более это полезно в вызовах sub. Почти всегда строка-замена должна содержать в себе части исходной строки, найденные при сопоставлении с регулярным выражением. Для этого в строке-замене можно использовать обозначения \1, \2 и т.д. - они означают 1-ю, 2-ю и т.д. группы.
sub(r'(^[a-z]*)(\d*)([a-z]*$)',r'[\1][\2][\3]','abc123xyz')