re - регулярные выражения

Формирование регулярного выряжения

  • ^ - привязка к началу строки или подстроки (зависит от флагов M и S)

  • $ - привязка к концу строки или подстроки (зависит от флагов M и S)

  • A - привязка к началу строки или подстроки (не зависит от флагов)

  • z - привязка к концу строки или подстроки (не зависит от флагов)

  • [] - внутри указываются символы, которые могут встречаться
    • [0-9] - любая цифра
    • [a-яА-ЯёЁ] - любая русская буква
    • [^3] - не цифра 3
  • d - любая цифра

  • D - НЕ цифра

  • w - любая буква, цифра и символ подчеркивания

  • W - НЕ буква, цифра и символ подчеркивания

  • s - любой пробельный символ

  • S - НЕ пробельный символ

  • {n} - n вхождений символа в строку

  • {n, } - n или более вхождений символа в строку

  • {n, m} - не менее n и не более m вхождений символа в строку

  • * - 0 или более вхождение смвола в строку

  • + - 1 или более вхождение символа в строку

  • ? - ни одного или 1 вхождение символа в строку

  • (n)|(m) - n или m

  • (?P<tag>) - тег для группы

    >>> email = "test@mail.ru"
    >>> р = re.compile(r"""
            (?P<name>[a-z0-9.-]+) # название ящика
            @
            (?P<host>(?:[a-z0-9-]+\.)+[a-z]{2,6}) # домен
        """, re.I | re.VERBOSE)
    >>> r = p.search(email)
    >>> r.group("name")
    'test'
    >>> r.group("host")
    'mail.ru'
    
  • (?P=tag) - обращение к группе внутри регулярки

  • (?aiLmsux) - флаги регулярного выражения

  • (?#...) - коментарии, текст внутри скобок игнорируется

  • (?=...) - положительный просмотр вперед

    >>> s = "textl, text2, textЗ text4"
    >>> р = re.compile(r"\w+(?=[,])", re.S | re.I) # все слова, после которых есть запятая
    >>> p.findall(s)
    ['text1', 'text2']
    
  • (?!...) - отрицательный просотр вперед

    >>> s = "textl, text2, textЗ text4"
    >>> р = re.compile(r"[a-z]+[0-9] (?![,])", re.S | re.I) # все слова, после которых нет запятой
    >>> p.findall(s)
    ['textЗ', 'text4']
    
  • (?<=...) - положительный просмотр назад

    >>> s = "textl, text2, textЗ text4"
    >>> р = re.compile(r"(?<=[,][ ])[a-z]+[0-9]", re.S | re.I) # все слова, перед которыми есть запятая с пробелм
    >>> p.findall(s)
    ['text2', 'text3']
    
  • (?<!...) - отрицательный просотр назад

    >>> s = "textl, text2, textЗ text4"
    >>> р = re.compile(r"(?<![,]) ([a-z]+[0-9])", re.S | re.I) # все слова, перед которыми есть пробел но нет запятой
    >>> p.findall(s)
    [text4']
    
  • (?(id или name) шаблон1|шаблон2) - если группа с номером. или названием найдена, то должно выполняться условие из параметра шаблон1, в противном случае должно выпол­няться условие из параметра шаблон2.

    >>> s = "textl 'text2' 'textЗ text4, text5"
    >>> р = re.compile(r"(')?([a-z]+(0-9]) (?(1) '1,)", re.S | re.I) # все слова которые находятся внутри апострофа, либо после слова есть запятая
    >>> p.findall(s)
    [("'", 'text2'), ('', 'text4')]
    
  • `` -

Все квантификаторы являются “жадными”. При поиске соответствия ищется самая длинная подстрока, соответствующая шаблону, и не учитываются более короткие соответствия. Чтобы ограничить жадность, необходимо после квантификатора указать символ ?

>>> s = "<b>Textl</b>Text2<b>Text3</b>"
>>> р = re.compile(r"<b>.*</b>", re.S)
>>> р1 = re.compile(r"<b>.*?</b>", re.S)
>>> p.findall(s)
['<b>Textl</b>Text2<b>Toxt3</b>']
>>> p1.findall(s)
['<b>Textl</b>', '<b>Text3</b>']
>>> s = 'test text'
>>> p = re.compile(r'([a-z]+((st)|(xt)))', re.S)
>>> p1 = re.compile(r'([a-z]+(?:(?:st)|(?:xt)))', re.S)
>>> p.findall(s)
[('test', 'st', 'st', ''), ('text', 'xt', 'xt')]
>>> p1.findall(s)
['test', 'text']
>>> s = "<b>Textl</b>Text2<b>Text3</b>"
>>> р = re.compile(r"<([a-z]+)>(.*?)</\1>", re.S | re.I)
>>> р1 = re.compile(r"<(?P<tag>[a-z]+)>(.*?)</(?P=tag))>", re.S | re.I)
>>> p.findall(s)
[('b', 'Text1'), ('b', 'Text3')]
>>> p1.findall(s)
[('b', 'Text1'), ('b', 'Text3')]
def select(r, xs):
    """возвращает список, из найденных груп в исходном списке
    :param r: регулярка
    :param xs: список строк для парсинга"""
    return [m.group() for m in (re.match(r, x) for x in xs) if m]

l = ['aaa', 'aab', 'abb', 'bbb']
print select(r'a*', l), "беру любое кол-во \"a\", даже нулевое!"
print select(r'a+', l), "любое ненулевое кол-во, беру всё!"
print select(r'a*?', l), "хочу 0+, беру минимум (т.е. не возьму ничего!)"
print select(r'a+?', l), "хочу 1+, беру минимум (т.е. одну штуку)"
print select(r'a?', l), "хочу (и беру) одну или ничего!"
print select(r'a{,2}', l), "хочу (и беру) до двух штук!"
print select(r'a{1,2}?', l), "хочу одну-две штуки, возьму минимум (одну)!"
print select(r'a{2}', l), "хочу (и беру) ровно две!"

# ['aaa', 'aa', 'a', ''] беру любое кол-во "a", даже нулевое!
# ['aaa', 'aa', 'a'] любое ненулевое кол-во, беру всё!
# ['', '', '', ''] хочу 0+, беру минимум (т.е. не возьму ничего!)
# ['a', 'a', 'a'] хочу 1+, беру минимум (т.е. одну штуку)
# ['a', 'a', 'a', ''] хочу (и беру) одну или ничего!
# ['aa', 'aa', 'a', ''] хочу (и беру) до двух штук!
# ['a', 'a', 'a'] хочу одну-две штуки, возьму минимум (одну)!
# ['aa', 'aa'] хочу (и беру) ровно две!
s = 'aa,a ab aa aaa'
print re.findall(r'a+', s), "выбираю слова по подстроке, но могут быть неверные выборки!"
print re.findall(r'\Wa+\W', s), "выбираю слова с небуквами по бокам и беру вместе с небуквами"
print re.findall(r'\sa+\s', s), "выбираю слова с пробелами по бокам и беру вместе с пробелами"
print re.findall(r'\ba+\b', s), "выбираю слова по границам слов, не беру сами границы!"
print re.findall(r'^a+', s), "выбираю слово в начале строки"
print re.findall(r'a+$', s), "выбираю слово в конце строки"

# ['aa', 'a', 'a', 'aa', 'aaa'] выбираю слова по подстроке, но могут быть неверные выборки!
# [',a ', ' aa '] выбираю слова с небуквами по бокам и беру вместе с небуквами
# [' aa '] выбираю слова с пробелами по бокам и беру вместе с пробелами
# ['aa', 'a', 'aa', 'aaa'] выбираю слова по границам слов, не беру сами границы!
# ['aa'] выбираю слово в начале строки
# ['aaa'] выбираю слово в конце строки
s = 'a\nab\nabc'
print "по-умолчанию точка не захватывает переводы строк, а ^ и $ обозначают границы всего текста:\n", (re.findall(r'^.+$', s))
print "^ и $ теперь обрабатывают подстроки:\n", (re.findall(r'(?m)^.+$', s))
print "точка захватывает и переводы строк:\n", (re.findall(r'(?s)^.+$', s))
print "\A\Z всегда обозначают границы текста:"
print re.findall(r'\A.+\Z', s)
print re.findall(r'(?m)\A.+\Z', s)
print re.findall(r'(?s)\A.+\Z', s)

# по-умолчанию точка не захватывает переводы строк, а ^ и $ обозначают границы всего текста:
# []
# ^ и $ теперь обрабатывают подстроки:
# ['a', 'ab', 'abc']
# точка захватывает и переводы строк:
# ['a\nab\nabc']
# \A\Z всегда обозначают границы текста:
# []
# []
# ['a\nab\nabc']

Атрибуты модуля

re.L
re.LOCALE

флаг, учитывать настройки локали

re.I
re.IGNORECASE

флаг, игнорировать регистр

re.M
re.MULTILINE

флаг, поиск в строке, состоящей из нескольких подстрок

re.S
re.DOTALL

флаг, метасимвол точка будет соответсвовать любому символу, включая символ перевода строки n

re.X
re.VERBOSE

флаг, пробелы и символы перевода строк будут игнорированы

re.U
re.UNICODE

флаг, w, W, b, B, d, D, s, S будут соответствовать юникод символам (в 3 питоне флаг установлен по умолчанию)

re.A
re.ASCII

флаг, w, W, b, B, d, D, s, S будут соответствовать обычным символам

Методы модуля

re.compile(expr[, flag | flag...])
Параметры:expr (str) – регулярное выражение
Parma flags:флаги модуля

возвращает SRE_Pattern

re.escape(<Строка>)

возвращает строку, с экранированными специальными символами, полученной от пользователя. Эту строку в дальнейшем можно безопасно исполь­зовать внутри регулярного выражения.

>>> print(re.escape(r"[] () .*"))
'\[\]\(\)\.\*''
re.findall(<Шаблон>, <Строка>[, <Модификатор>])

возвращает список найденных фрагментов

re.finditer(<Шаблон>, <Строка>[, <Модификатор>])

возвращает итератор найденных фрагментов

re.match(expr, string[, flags])
Параметры:
  • expr (str) – регулярное выражение
  • string (str) – искомая строка
  • flags – флаг

проверяет соотвествие с началом строки, если соответсвие найдено, возвращается Match иначе None

re.search(expr, string[, flags])
Параметры:
  • expr (str) – регулярное выражение
  • string (str) – искомая строка
  • flags – флаг

проверяет соотвествие с любой частью строки, если соответсвие найдено, возвращается Match иначе None

re.split(<Шaблoн>, <Исходная строка>[, <Лимит>[, fla9s=O]])

возвращает список, полученный путем разбиения строки по шаблону

re.sub(<Шаблон>, <Новьм фрагмент или ссылка на функцию>, <Строка для замены>[, <Максимальное количество замен>[, flags=O]])

ищет все совпадения с шаблоном и заменяет их указанным значением. Внутри нового фрагмента можно использовать обратные ссылки номер, g<номер> и g<название>, соответствующие группам внутри шаблона.

В качестве первого параметра можно указать ссылку на функцию. В эту функцию будет передаваться объект Match, соответствующий найденному фрагменту. Результат, возвра­щаемый этой функцией, служит фрагментом для замены.

re.subn(<Шаблон>, <Новьм фрагмент или ссылка на функцию>, <Строка для замены>[, <Максимальное количество замен>[, flags=O]])

аналогичен sub(), но возвращает кортеж из двух элементов, измененной строки и колчества замен

Классы модуля

class re.SRE_Pattern

объект возвращаемый методом compile()

groups

количесвто груп в шаблоне

groupindex

словарь с названиями групп и их номерами

findall(<Cтpoкa>[, <Начальная позиция>[, <Конечная позиция>]])

возвращает список найденных фрагментов. Если внутри шаблона есть более одной груnnы, то каждый элемент сnиска будет кортежем, а не строкой.

>>> р = re.compi1e(r"[0-9]+")
>>> p.findall("2007, 2008, 2009, 2010, 2011")
['2007', '2008', '2009', '2010', '2011']
finditer(<Строка>[, <Начальная позиция>[, <Конечная позиция>]])

возвращает итератор найденных фрагментов. Если внутри шаблона есть более одной груnnы, то каждый элемент сnиска будет кортежем, а не строкой.

match(string [, start] [, end])
Параметры:
  • string (str) – искомая строка
  • end (int) – конечная позиция
Parma int start:
 

начальная позиция

проверяет соотвествие с началом строки, если соответсвие найдено, возвращается Match иначе None.

search(string [, start] [, end])
Параметры:
  • string (str) – искомая строка
  • end (int) – конечная позиция
Parma int start:
 

начальная позиция

проверяет соотвествие с любой частью строки, если соответсвие найдено, возвращается Match иначе None

split(<Исходная строка>[, <Количесвто замен>])

возвращает список, полученный путем разбиения строки по шаблону

>>> р = re.compi1e(r"[\s, .]+")
>>> p.sp1it("word1, word2\nword3\r\nword4.word5")
['word1', 'word2', 'word3', 'word4', 'word5']
sub(<Новый фрагмент или ссылка на функцию>, <Строка для замены>[, <максимальное количесвто замен>])

ищет все совпадения с шаблоном и заменяет их указанным значением. Внутри нового фрагмента можно использовать обратные ссылки номер, g<номер> и g<название>, соответствующие группам внутри шаблона.

В качестве первого параметра можно указать ссылку на функцию. В эту функцию будет передаваться объект Match, соответствующий найденному фрагменту. Результат, возвра­щаемый этой функцией, служит фрагментом для замены.

>>> р = re.compile(r"<(?P<tag1>[a-z]+)><(?P<tag2>[a-z]+)>")
>>> p.sub(r"<\2><\1>", "<br><hr>") # \номер
<hr><br>'
>>> р.sub(r"<\g<2>><\g<1>>", "<br><hr>") # \g<номер>
'<hr><br>'
>>> p.sub(r"<\g<tag2>><\g<tag1>>", "<br><hr>") # \g<название>
'<hr><br>'
subn(<Новый фрагмент или ссылка на функцию>, <Строка для замены>[, <максимальное количесвто замен>])

аналогичен sub(), но возвращает кортеж из двух элементов, измененной строки и колчества замен