Kodomo

User

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

Форматирование выдачи.

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

RE

Synonyms

Description

Examples

Van[yj]a

В квадратных скобочках указываются символы, которые могут стоять в данной позиции. При этом можно использовать тире для того, чтобы указывать последовательность символов, например: [0-9] (все цифры), [a-z] все маленькие буквы, [a-zA-Z] (все буквы)

+ Vanya
+ Vanja
- Vania

Van[^ji]

Если первым символом после открывающей квадратной скобочки является ^, то в квадратных скобочках перечисляются символы, которые НЕ могут стоять в данной позиции, т.е. остальные все символы, кроме этих, могут.

+ Vanya
+ Vanna
- Vanja
- Vania

Van{3}ya

Vannnya

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

+ Vannnya
- Vanya

Van{1,3}ya

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

+ Vannnya
+ Vanya
- Vaya
- Vannnnya

Van{2,}ya

Если максимальное количество раз пропущено, то это значит что количество повторений сверху не ограничено и может быть бесконечным

+ Vannya
+ Vannnnnya
- Vanya

Van?ya

Van{0,1}ya

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

+ Vaya
+ Vanya
- Vannya

Van*ya

Van{0,}ya

Звездочка означает 0 или большее количество повторений непосредственно предшествующего символа

+ Vaya
+ Vanya
+ Vannya

Van+ya

Van{1,}ya

Плюсик означает 1 или большее количество повторений непосредственно предшествующего символа

- Vaya
+ Vanya
+ Vannya

Va.ya

Точка означает любой символ, кроме символа конец строки (\n)

+ Va.ya
+ Vanya
- Vaya

Va\.ya

Backslash «защищает» символ, который следует за ним, т.е. делает символ обычным.

+ Va.ya
- Vanya
- Vaya

(Va)+nya

Скобочки используются для группировки

+ Vanya
+ VaVanya
- Vavanya

^Van

^ обозначает начало строки

+ Vanya
+ Vanzzz
- Ivan

ya$

$ обозначает конец строки

+ Kolya
- Roma

Vanya|Kolya

Выбор одного из нескольких вариантов

+Vanya
+ Kolya
- Roma

Van(ya|e)

Выбор одного из нескольких вариантов и круглые скобки

+Vanya
+ Vane
- Vani

\s

[ \t\n\r\f]

Space char – символ пробела

\S

[^ \t\n\r\f]

! Space char – не символ пробела

\d

[0-9]

Digit

\D

[^0-9]

! Digit

\w

[a-zA-Z0-9]

Word char – буква

\W

[^a-zA-Z0-9]

! Word char – не буква

\b

Граница слова

\B

НЕ Граница слова

Составьте регулярное выражение, которое бы подходило к:

Использование регулярных выражений

Теперь, когда мы рассмотрели несколько простых регулярных выражений, как мы можем использовать их в Python? Модуль re предоставляет интерфейс для регулярных выражений.

>>>import re

Выполнение сопоставлений

После того, как у вас есть объект, представляющий скомпилированное регулярное выражение, что вы с ним будете делать? Объекты шаблонов имеют несколько методов. Мы рассмотрим самые необходимые.

match()
Определить, начинается ли совпадение регулярного выражения с начала строки
search()
Сканировать всю строку в поисках первого совпадения с регулярным выражением
findall()
Найти все подстроки совпадений с регулярным выражением и вернуть их в виде списка

Если не было найдено ни одного совпадения, то match() и search() возвращают None. Если поиск успешен, возвращается обьект (MatchObject), содержащий информацию о совпадении: где оно начинается и заканчивается, подстрока соответствия, и так далее. Теперь вы можете попробовать сравнить строки для регулярного выражения [a-z]+. Пустая строка ему не будет соответствовать, потому что + означает повторение «один или больше» раз. match() в этом случае должен вернуть None, что и видим:

>>> m=re.match(r'[a-z]+', '')
>>> print m
None

Теперь попробуем строку, которая должна совпасть с шаблоном: 'tempo'. В этом случае match() вернет MatchObject, который вы можете разместить в какой-то переменной, чтобы использовать ее в дальнейшем:

>>> m = re.match(r'[a-z]+', 'tempo')

Теперь вы можете вызывать MatchObject для получения информации о соответствующих строках. Для MatchObject также имеется несколько методов и атрибутов, наиболее важными из которых являются:

group()
Вернуть строку, сошедшуюся с регулярным выражением
start()
Вернуть позицию начала совпадения
end()
Вернуть позицию конца совпадения
span()
Вернуть кортеж (start, end) позиций совпадения

>>> m.group()
'tempo'
>>> m.start(), m.end()
(0, 5)
>>> m.span()
(0, 5)

Так как метод match() проверяет совпадения только с начала строки, start() всегда будет возвращать 0. Однако метод search() сканирует всю строку, так что для него начало не обязательно в нуле:

>>> print re.match(r'[a-z]+', '::: message')
None
>>> m = re.search(r'[a-z]+', '::: message') ; print m
<_sre.SRE_Match object at 0x...>
>>> m.group()
'message'
>>> m.span()
(4, 11)

В реальных программах наиболее распространенный стиль это хранение MatchObject в переменной, а затем проверка по None. Обычно это выглядит следующим образом:

m = re.match(r'.+', 'string goes here' )
if m:
    print 'Match found: ', m.group()
else:
    print 'No match'

Два метода возвращают все совпадения для шаблона. findall() возвращает список совпавших подстрок:

>>> re.findall(r'\d+', '12 drummers drumming, 11 pipers piping, 10 lords a-leaping')
['12', '11', '10']

Метод findall() должен создать полный список, прежде чем он может быть возвращен в качестве результата.

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

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

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

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

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

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

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

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

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

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

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

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

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

re.split

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

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

Форматирование выдачи

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

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

Место, куда нужно вставить ваши данные, обозначается в шаблоне знаком {0}.

Пример:

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

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

Примеры:

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

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

>>> message = '{filename}:{line_no}: {error_text}'
>>> print message.format(line_no=10, filename="hello.txt", error="No error")
hello.txt:10: No error

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

2012/4/Python/8/Record (last edited 2014-03-31 05:40:44 by stavrovskaya)