В языке Python регулярные выражения представляются стандартной библиотекой.
Когда мы пишем регулярное выражение мы хотим чтобы обратный слэш вел себя как обратный слэш.
x = "hello\nworld" print(x) x = r"hello\nworld" # сырая (raw) строка print(x)
Для описания шаблонов регулярных выражений используются именно сырые строки.
Основные функции
В модуле re находятся четыре основные функции для работы с регулярными выражениями:print(re.match) # проверят подходит ли данная строка под данный шаблон print(re.search) # находит первую подстроку, которая подходит под данный шаблон print(re.findall) # находит все подстроки, которые подходят под данный шаблон print(re.sub) # заменить все вхождения подстрок, которые подходят под наш шаблон, чем-нибудь другим
Строка "abc" подходит под шаблон "abc".
Функция match берет строку и бежит с самого начала нашей строки до тех пор пока какой-нибудь префикс нашей строки не подойдет под данное регулярное выражение:
pattern = r"abc" string = "abcd" match_object = re.match(pattern, string) print(match_object)
Однако, если мы хотим найти вхождение нашего шаблона в строку, то мы можем использовать функцию search:
pattern = r"abc" string = "babc" match_object = re.search(pattern, string) print(match_object)
Те числа, которые возвращаются нам внутри span-a, это те же числа, которые мы бы использовали при слайсинге:
Функции findall и sub позволяют найти все вхождения шаблона внутри текста и заменить эти подстроки на что-то другое:
string = "abc, a.c, aac, a-c, aBc, azc" all_inclusions = re.findall(pattern, string) print(all_inclusions) fixed_typos = re.sub(pattern, "abc", string) print(fixed_typos)
Метасимволы
Метасимволы . ^ $ * + ? { } [ ] \ | ( ) позволяют расширять то множество строк, которые подходят под наш шаблон.
pattern = r"a[abc]c" # [] -- можно указать множество подходящих символов string = "abc" # строки "aac", "abc", "acc" будут подходить под шаблон match_object = re.match(pattern, string) print(match_object)
Если мы хотим просто найти символ вопросительного знака, то должны экранировать его с помощью обратного слэша:
import re pattern = r" english\?" string = "Do you speak english?" match = re.search(pattern, string) print(match)
Можно указать диапазон подходящих символов:
pattern = r"a[a-zA-Z]c" string = "aBc" match_object = re.search(pattern, string) print(match_object)
Символ циркумфлекс ^ используется для описания множества неподходящих символов:
pattern = r"a[^a-zA-Z]c" string = "a.c" match_object = re.search(pattern, string) print(match_object)
Для некоторых групп символов существует короткая запись:
- \d ~ [0-9] -- цифры
- \D ~ [^0-9]
- \s ~ [ \t\n\r\f\v] -- пробел, табуляция, перенос строки, перенос каретки, перенос страницы, вертикальная табуляция
- \S ~ [^ \t\n\r\f\v]
- \w ~ [a-zA-Z0-9_] -- буквы + цифры + _
- \W ~ [^a-zA-Z0-9_]
Их можно совмещать:
Любой символ кроме переноса строки подходит под метасимвол точки.
Если нас интересует только положительное число (> 0) включений, то используется символ +:
Используя метасимвол ? можно указать, что нас интересует 0 или 1 вхождение символа b:
А вот если нас интересует конкретно число вхождений или от какого-то до какого-то количества, то можно использовать метасимвол фигурных скобок:
Метасимволы повтора * и + являются жадными, т.е. они пытаются вовлечь в себя как можно больше символов при том чтобы наше регулярное выражение удовлетворилось целиком. При жадном подходе мы сначала пытаемся выбрать строку максимальной длины, которая нас удовлетворяет, а затем проверить, а вот то, что осталось от нашей строки, оно подходит под остаток шаблона, который у нас остался, если нет, то мы выкидываем один символ с конца и снова проверяем.
Можно пойти не жадным способом, т.е. найти наименьшее число вхождений, которое бы удовлетворило наше регулярное выражение. Для этого мы можем использовать ? после нашего метасимвола.
Через метасимвол или | можно указать, что нам подходит одна из групп символов:
Метасимвол | обладает наименьшим приоритетом в регулярных выражениях.
Посредством групп мы запоминаем какие символу попал в конкретную группу:
Для того чтобы достать значение группы используется метод group:
Можно использовать найденную группу прямо внутри регулярного выражения:
Мы можем переиспользовать эту группу внутри функции sub:
При использовании групп функция findall возвращает кортеж групп.
pattern = r"a[\w.]c" string = "a.c" match_object = re.search(pattern, string) print(match_object)
Любой символ кроме переноса строки подходит под метасимвол точки.
Метасимволы повтора
Также можно указывать, что нас интересует некоторое число повторов символа или группы символов:pattern = r"ab*a" # любое число символов b, включая 0 string = "aa, aba, abba" all_inclusions = re.findall(pattern, string) print(all_inclusions)
Если нас интересует только положительное число (> 0) включений, то используется символ +:
pattern = r"ab+a" string = "aa, aba, abba" all_inclusions = re.findall(pattern, string) print(all_inclusions)
Используя метасимвол ? можно указать, что нас интересует 0 или 1 вхождение символа b:
pattern = r"ab?a" string = "aa, aba, abba" all_inclusions = re.findall(pattern, string) print(all_inclusions)
А вот если нас интересует конкретно число вхождений или от какого-то до какого-то количества, то можно использовать метасимвол фигурных скобок:
pattern = r"ab{2,4}a" string = "aa, aba, abba, abbba, abbbba" all_inclusions = re.findall(pattern, string) print(all_inclusions)
Метасимволы повтора * и + являются жадными, т.е. они пытаются вовлечь в себя как можно больше символов при том чтобы наше регулярное выражение удовлетворилось целиком. При жадном подходе мы сначала пытаемся выбрать строку максимальной длины, которая нас удовлетворяет, а затем проверить, а вот то, что осталось от нашей строки, оно подходит под остаток шаблона, который у нас остался, если нет, то мы выкидываем один символ с конца и снова проверяем.
pattern = r"a[ab]+a" string = "abaaba" print(re.match(pattern, string)) print(re.findall(pattern, string))
Можно пойти не жадным способом, т.е. найти наименьшее число вхождений, которое бы удовлетворило наше регулярное выражение. Для этого мы можем использовать ? после нашего метасимвола.
pattern = r"a[ab]+?a" string = "abaaba" print(re.match(pattern, string)) print(re.findall(pattern, string))
Группировка символов
Это нужно для того чтобы мы могли использовать метасимволы повтора для какой-нибудь группы символов, а не для одиночного символа. Для группировки используются круглые скобки:pattern = r"(test)*" string = "testtest" print(re.match(pattern, string))
pattern = r"(test|text)*" string = "testtext" print(re.match(pattern, string))
Посредством групп мы запоминаем какие символу попал в конкретную группу:
pattern = r"((abc)|(test|text)*)" string = "abc" match = re.match(pattern, string) print(match) print(match.groups())
Для того чтобы достать значение группы используется метод group:
pattern = r"Hello (abc|test)" string = "Hello abc" match = re.match(pattern, string) print(match) print(match.group(0)) print(match.group(1))
Можно использовать найденную группу прямо внутри регулярного выражения:
import re pattern = r"(\w+)-\1" string = "test-test" match = re.match(pattern, string) print(match)
Мы можем переиспользовать эту группу внутри функции sub:
import re pattern = r"(\w+)-\1" string = "test-test chow-chow" duplicates = re.sub(pattern, r"\1", string) print(duplicates)
При использовании групп функция findall возвращает кортеж групп.
import re pattern = r"((\w+)-\2)" string = "test-test chow-chow" duplicates = re.findall(pattern, string) print(duplicates)
Флаги
Можно указать, что нас не интересует являются ли буквы заглавными или строчными.import re x = re.match(r"(te)*?xt", "TEXT", re.IGNORECASE | re.DEBUG) print(x)
Комментариев нет:
Отправить комментарий