2010-09-28_RegExps

advertisement
RegExp
•
Регуля́рные
выраже́ния
(англ.
regular
expressions,
сокр. RegExp, RegEx, жарг. регэ́кспы или ре́гексы) — это
формальный язык поиска и осуществления манипуляций с
подстроками в тексте, основанный на использовании метасимволов
(символов-джокеров, англ. wildcard characters). По сути это строкаобразец (англ. pattern, по-русски её часто называют «шаблоном»,
«маской»), состоящая из символов и метасимволов и задающая
правило поиска.
•
Функции для работы со строками с помощью регулярных выражений
находятся в модуле по имени re (regular expressions)
Для чего нужны регулярные
выражения?
Регулярные выражения применяют для:
а) поиска подстроки, удовлетворяющей шаблону регулярного
выражения, в строке.
б) поиска и замены подстроки, удовлетворяющей шаблону
регулярного выражения, в строке.
в) проверки на соответствие заданной строки шаблону.
г) извлечения подстроки, удовлетворяющей шаблону регулярного
выражения, из строки.
Создать
откомпилированный
шаблон
регулярного
выражения позволяет функция compile(). Функция имеет
следующий формат:
<Шаблон> = re.compile(<Регулярное выражение>[, <Модификатор>])
Перед строками, содержащими регулярные выражения,
указан модификатор r. Иными словами, мы используем
неформатированные строки.
Если модификатор не указать, то все слеши необходимо
будет экранировать.
p = re.compile(r”^\w+$”)
p = re.compile(“^\\w+$”)
Специальные обозначения
Символ
Что обозначает
“.”
“^”
“$”
“*”
Любой символ
Начало строки
Конец строки
Повторение фрагмента 0 или более раз:
«go*gle» соответствует ggle, gogle, google и др.
То же, но хотя бы 1 раз
Предыдущий фрагмент либо присутствует, либо
отсутствует: «colou?r» соответствует и color, и colour
Повторение предыдущего фрагмента от m до n раз
m и более повторений
не более n повторений
Любой символ из набора в скобках
Любой символ не из набора в скобках
С помощью символа обратной косой черты можно
отменять специальное значение следующего за ней
символа, например «\ (» - соответствует «(»
Соответствует символам справа или слева
Скобки, внутри которых находится регулярное выражение
“+”
“?”
“{m, n}”
“{m,}”
“{,n}”
“[…]”
“[^…]”
“\”
“|”
“(…)”
• Помимо специальных обозначений, в регулярном
выражении только буквы и цифры могут входить в
качестве самих себя. Для внесения других символов
необходимо использовать обратную косую черту.
Например, скобку можно задать как «\ (»
• С регулярным выражением можно не только сопоставлять
строки (подходит – не подходит), но и искать строки,
удовлетворяющие регулярному выражению, в тексте.
____________
В таблице ниже приведены регулярные выражения и
примеры сопоставимых с ними и не сопоставимых с ними
строк
Запись
шаблона
Примеры строк,
удовлетворяющих
шаблону
Примеры
строк, не
удовлетворяю
щих шаблону
Примечание
“.*”
“любая строка”
“[abc]+”
“a”, “baba”, “abba”
“ ”, “adidas”
Непустая строка из символов a,b,c
“[a-z]+”
“aakkaa”, “zyx”, “code”
Непустая строка из строчных
латинских букв
“[a-h]
[1-8]”
“e2”, “e4”, “h1”
“ ”, “Abba”,
“ADIDAS”
“k1”, “h0”, “a”
“^From: .*”
“From: abc@mail.ru”
“ From:nospam”
“^[A-Z]
[a-z]*$”
“One”, “Name”
“Two names”,
“other”
“A?B?C?”
“”, “A”, “B”, “C”, “AB”,
“AC”, “BC”, “ABC”
“BA”, “AA”,
“A?B?C?”
Произвольное число раз
повторяется определенный символ
Координаты клетки шахматной
доски
Поле электронного письма
Строка с записью одного слова
латинскими буквами, с большой
буквы
В столбце примера приведены все
строки, которые удовлетворяют
шаблону
Запись
шаблона
Примеры строк,
удовлетворяющих
шаблону
Примеры строк,
Примечание
не
удовлетворяющих
шаблону
“(яблоко |
апельсин)”
“яблоко”, “апельсин”
“(1)”, “()”, “(12345)”,
“\(111\)”
Либо “яблоко”, либо
“апельсин”
“(яблоко |
апельсин ) +”
“яблоко ”, “апельсин
яблоко апельсин ”,
“апельсин ”
“апелько”,
“яблокоапельсин”
Положительное число
повторений
регулярного
выражения в скобках
“(кис+) +”
“кис”, “кискискис”,
“кисссскисскисссссс”
“киисс”
“[^():,.-]+”
“слова”, “слова и
пробелы”
“-”, “(скобки)”,
“запятые”
“кис” несколько раз с
любым числом букв
“с” на концах
Все, кроме указанных
после “^” знаков.
Заметьте, что “-”
может стоять только в
конце “[…]”, чтобы
обозначать саму себя
«Жадные» выражения
•
Все квантификаторы являются «жадными». При поиске соответствия ищется
самая длинная подстрока, соответствующая шаблону, и не учитываются более
короткие соответствия. Рассмотрим это на примере. Получим содержимое всех
тегов <b> вместе с тегами:
>>> s = "<b>Text1</b>Text2<b>Text3</b>"
>>> p = re.compile(r"<b>.*</b>", re.S)
>>> p.findall(s)
[‘<b>Text1</b>Text2<b>Text3</b>’]
•
Чтобы ограничить «жадность», необходимо после квантификатора указать
символ ?
>>> s = "<b>Text1</b>Text2<b>Text3</b>"
>>> p = re.compile(r"<b>.*?</b>", re.S)
>>> p.findall(s)
[‘<b>Text1</b>’ , ‘<b>Text3</b>’]
• Если необходимо получить содержимое без тегов, то нужный
фрагмент внутри шаблона следует разместить внутри круглых
скобок
>>>s = "<b>Text1</b>Text2<b>Text3</b>"
>>> p = re.compile(r"<b>(.*?)</b>", re.S)
>>> p.findall(s)
[‘Text1’ , ‘Text3’]
• *? - «не жадный» («ленивый») эквивалент *
• +? - «не жадный» («ленивый») эквивалент +
• {n,}? - «не жадный» («ленивый») эквивалент {n,}
Группы
• ()
Простая группа с захватом.
• (?: ) Группа без захвата.
То же самое, но заключённое в скобках выражение не
добавляется к списку захваченных фрагментов. Например, если
требуется найти или «здравствуйте», или «здрасте», но не
важно,
какое
именно
приветствие
найдено,
можно
воспользоваться выражением здра(?:сте|вствуйте).
• (?= ) Группа с проверкой впереди (zero-width positive lookahead
assertion). Продолжает поиск только если справа от текущей
позиции в тексте находится заключённое в скобки выражение.
При
этом
само
выражение
не
захватывается.
Например, говор(?=ить) найдёт «говор» в «говорить», но не
«говорит».
• К найденному фрагменту в круглых скобках внутри шаблона
можно обратиться с помощью механизма обратных ссылок.
\1 – порядковый номер круглых скобок
>>> s = "<b>Text1</b>Text2<I>Text3</I>"
>>> p = re.compile(r"<([a-z]+)>(.*?)</\1>", re.S | re.I)
>>> p.findall(s)
[(‘b’, ‘Text1’) , (‘I’, ‘Text3’)]
Функции
Для поиска первого совпадения с шаблоном предназначены
следующие функции:
 match() – проверяет соответствие с началом сторки
re.match(<Шаблон>, <Строка>[, <Модификатор>])
>>> p = r”[0-9]+”
>>> print “Найдено” if re.match(p, “str123”) else “Нет”
Нет
>>> print “Найдено” if re.match(p, “123str”) else “Нет”
Найдено
>>> p = re.compile(r”[0-9]+”)
>>> print “Найдено” if re.match(p, “123str”) else “Нет”
Найдено
 search() – проверяет соответствие с любой частью строки
re.search(<Шаблон>, <Строка>[, <Модификатор>])
>>> p = r”[0-9]+”
>>> print “Найдено” if re.search(p, “str123”) else “Нет”
Найдено
>>> p = re.compile(r”[0-9]+”)
>>> print “Найдено” if re.search(p, “str123”) else “Нет”
Найдено
Проверка e-mail на соответствие шаблону
# -*- coding: cp1251 -*import re
email = raw_input(“Введите e-mail: “)
pe = r"^([a-z0-9_.-]+)@(([a-z0-9-]+\.)+[a-z]{2,6})$"
p = re.compile(pe, re.I)
m = p.search(email)
if not m:
print “E-mail не соответствует шаблону”
else:
print “E-mail”, m.group(0), “соответствует шаблону”
print “ящик:”, m.group(1), “домен:”, m.group(2)
Результат выполнения:
Введите e-mail: unicross@mail.ru
E-mail unicross@mail.ru соответствует шаблону
ящик: unicross домен: mail.ru
Для поиска всех совпадений с шаблоном предназначены
следующие функции:
 findall() – ищет все совпадения с шаблоном
re.findall(<Шаблон>, <Строка>[, <Модификатор>])
>>> p = r”[0-9]+”
>>> re.findall(p, “1 2 3 4 5 6”)
[‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’]
>>> p = re.compile(r”[0-9]+”)
>>> re.findall(p, “1 2 3 4 5 6”)
[‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’]
 finditer() – аналогично функции findall(), но возвращает итератор,
а не список.
re.finditer(<Шаблон>, <Строка>[, <Модификатор>])
Получим содержимое между тегами:
>>> p = re.compile(r”<b>(.+?)</b>”, re.I | re.S)
>>> s = “<b>Text1</b>Text2<b>Text3</b>”
>>> for m in re.finditer(p, s):
print m.group(1)
Text1
Text3
Для замены в строке с помощью регулярных выражений
предназначены следующие функции и методы:
 sub() – ищет все совпадения с шаблоном и заменяет их
указанным значением. Если совпадения не найдены,
возвращается исходная строка.
 subn() – аналогичен sub(), но возвращает не строку, а кортеж из
двух элементов – измененной строки и количества
произведенных замен.
re.subn(<Шаблон>, <Новый фрагмент или ссылка на функцию>,
<Строка для замены>[, <Максимальное количество замен>])
>>> p = r”200[79]”
>>> re.subn(p, “2001”, “2007, 2008, 2009, 2010”)
(‘2001, 2008, 2001, 2010’, 2)
Download