Kodomo

Пользователь

Учебная страница курса биоинформатики,
год поступления 2010

Регулярные выражения, часть II. Форматирование выдачи.

Группы в регулярных выражениях

Когда мы ставим какую-нибудь часть регулярного выражения в скобки, питон запоминает ту часть входной строки, которую мы нашли этой парой скобок. Мы можем ей впоследствии пользоваться, ля этого нужно обращаться к ней по номеру скобок: скобки считаются по открывающей скобке начиная с 1. А способов пользоваться этим несколько:

Во-первых, когда мы получили match object из поиска регулярного выражения, мы можем получить строку, найденную парой скобок, с помощью методов group(), start() и end()

   1 >>> import re
   2 >>> m = re.match(r'Hello, (.+)!', 'Hello, Peter!')
   3 >>> m.group(1), m.start(1), m.end(1)
   4 ('Peter', 7, 12)

Во-вторых, мы можем в самом регулярном выражении требовать нахождения в выбранном месте того же текста, который мы уже один раз им же нашли группой. Такой приём называется back-reference, обратная ссылка. Для этого нужно в регулярном выражении использовать запись \1 \2 ... (\ и номер группы). Например:

   1 >>> expr = r'Hello, (.+)! How are you, \1\?'
   2 >>> bool(re.match(expr, 'Hello, world! How are you, world?'))
   3 True
   4 >>> bool(re.match(expr, 'Hello, world! How are you, Peter?'))
   5 False

Обратные ссылки ведут себя предсказуемым образом только в простейших случаях. В случае, если скобка стоит под каким-нибудь множителем (*, +, {} и т.п), в неё попадает только последняя из находок. Если в группу в регулярном выражении не попало текста, или она находится в не сработавшей ветке альтернативы, то питон в зависимости от случая либо запретит такой группой пользоваться, либо скажет, что она нашла пустую строку. Например:

   1 >>> m = re.match(r'(1)?2' ,'2')
   2 >>> m.group(1), m.start(1), m.end(1)
   3 (None, -1, -1)
   4 >>> m = re.match(r'([12])*' ,'111222')
   5 >>> m.group(1), m.start(1), m.end(1)
   6 ('2', 5, 6)

Поиск с заменой

Мы можем попросить питон заменить часть ту строки, которую мы нашли регулярным выражением, на какой-нибудь текст. Для этого в модуле re есть функция sub. Она принимает три аргумента: что искать, на что заменять, где искать. Функция sub ищет выражение во всех местах строки (т.е. ведёт себя как search). Например:

   1 >>> re.sub(r'\d+', '0', 'You have 100500 dollars on your bank account.')
   2 'You have 0 dollars on your bank account.'

Кроме того, мы можем в подставляемом выражении использовать обратные ссылки:

   1 >>> re.sub(r'Hello, (.*)!', r'Goodbye, \1...', 'Hello, cruel world!')
   2 'Goodbye, cruel world...'

re.split

Ещё одна полезная возможность у регулярных выражений – они позволяют использовать регулярное выражение для разбиения строки на части:

   1 >>> re.split(r',\s*', '1,       2,3,4')
   2 ['1', '2', '3', '4']

str.format

Когда мы пишем программу, которая собирает какие-то данные, возникает потребность во-первых как-то перемежать данные с текстом, во-вторых, при выводе чисел, форматировать их каким-нибудь специальным образом – с десятичной точкой или без, отводить под число какое-то число символов, писать его с нулями или пробелами вначале или с пробелами в конце и т.п. Каждую такую задачу можно решить самостоятельно, но это довольно частая потребность, а каждый раз решать одну и ту же задачу нудно и неинтересно. Поэтому в питоне для этого есть готовое средство: метод format у строк.

Работает он так: вы пишете строку с описанием того, куда и как вставить, и вызываете для этой строки метод format с аргументами, что вставить.

Пример:

   1 >>> who = "world"
   2 >>> print "Hello, {0}!".format(who)
   3 "Hello, world!"

Описания бывают вида:

Примеры:

   1 >>> print 'Name: {0:5}, Surname: {1:5}'.format('w', 'orld')
   2 Name: w    , Surname: orld 
   3 >>> print "4 + 5 = {0:05.3f}!".format(9)
   4 4 + 5 = 9.000!

Возможности указания форматов в этом месте очень велики и мы не будем всё охватывать в наших лекциях, но отошлём вас к документации.