Kodomo

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

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

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

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 предоставляет интерфейс для регулярных выражений, что позволяет компилировать регулярные выражения в объекты, а затем выполнять с ними сопоставления.

Компиляция регулярных выражений

Регулярные выражения компилируются в объекты шаблонов, имеющие методы для различных операций, таких как поиск вхождения шаблона или выполнение замены строки.

   1 >>>import re
   2 >>>p = re.compile(r'ab*')
   3 >>>print p
   4 <_sre.SRE_Pattern object at 0x...>

re.compile() также принимает необязательные аргументы, использующихся для включения различных особенностей и вариаций синтаксиса:

   1 >>> p = re.compile(r'ab*', re.IGNORECASE)

Регулярное выражение передается re.compile() как строка. Регулярные выражения обрабатываются как строки, поскольку не являются частью языка Python, и нет никакого специального синтаксиса для их выражения.

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

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

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

Если не было найдено ни одного совпадения, то match() и search() возвращают None. Если поиск успешен, возвращается обьект (MatchObject), содержащий информацию о совпадении: где оно начинается и заканчивается, подстрока соответствия, и так далее.

   1 >>> import re
   2 >>> p = re.compile(r'[a-z]+')

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

   1 >>> p.match("")
   2 >>> print p.match("")
   3 None

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

   1 >>> m = p.match(r'tempo')

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

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

   1 >>> m.group()
   2 'tempo'
   3 >>> m.start(), m.end()
   4 (0, 5)
   5 >>> m.span()
   6 (0, 5)

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

   1 >>> print p.match(r'::: message')
   2 None
   3 >>> m = p.search(r'::: message') ; print m
   4 <_sre.SRE_Match object at 0x...>
   5 >>> m.group()
   6 'message'
   7 >>> m.span()
   8 (4, 11)

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

   1 p = re.compile( ... )
   2 m = p.match(r'string goes here' )
   3 if m:
   4     print 'Match found: ', m.group()
   5 else:
   6     print 'No match'

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

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

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

Функции на уровне модуля

Вам не обязательно нужно создавать объекты шаблонов и вызывать их методы; модуль re также предоставляет функции верхнего уровня match(), search(), findall(), sub() и так далее. Эти функции принимают те же аргументы, что и для шаблонов, со строкой РВ в качестве первого аргумента и также возвращают None или MatchObject.

   1 >>> print re.match(r'From\s+', 'Fromage amk')
   2 None
   3 >>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998')
   4 <_sre.SRE_Match object at 0x...>

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

Должны вы использовать эти функции или шаблоны с методами? Это зависит от того, как часто будет использоваться регулярное выражение и от вашего личного стиля кодинга. Если регулярное выражение используется только в одном месте кода, то такие функции, вероятно, более удобны. Если программа содержит много регулярных выражений, или повторно использует одни и те же в нескольких местах, то будет целесообразно собрать все определения в одном месте, в разделе кода, который предварительно компилирует все регулярные выражения. В качестве примера из стандартной библиотеки, вот кусок из xmllib.py:

   1 ref = re.compile( ... )
   2 entityref = re.compile( ... )
   3 charref = re.compile( ... )
   4 starttagopen = re.compile( ... )