Написание регексов (Regexp), примеры
2010-01-30
python
regexp
инструкция
1. Выбор опорного текста
Для начала нужно определить опорный текст, который лежит рядом с целевым и который не меняется.
Например: нужно получить ссылку и текст ссылки из html страницы:
<a href="http://google.com">this google</a>
жирным выделен опорный текст, вписываем его в шаблон: <a href="!">!</a>, вместо восклицательных знаков нужно вписать шаблон целевого текста. Опорный текст можно тоже описывать шаблонами, например если неизвестно сколько пробелов между "<a" и "href" - можно использовать шаблон "\s+?" который означает что тут должны быть символы разделители, 1 или несколько, и выражение будет таким: <a\s+?href="!">!</a>
2. Выбор целевого текста (тот который нужно получить)
в данном случае можно по простому, выбрать весь текст: "(.+?)", "." означает любой символ, "+" - символов один или несколько, "?" - означает что текст не жадный. Подставляем в наше выражение: "<a href="(.+?)">(.+?)</a>"
Пример:
# coding: utf-8
import re
text = '<body> <a href="http://google.com">this google</a> <br/> <a href="http://yandex.ru">yandex</a> </body> '
d = re.findall(r'<a href="(.+?)">(.+?)</a>', text)
print d
Результат:
[('http://google.com', 'this google'), ('http://yandex.ru', 'yandex')]
Если мы хотим что-б 1 группа (ссылка) начиналась с текста "http://", то так и пишем: "(http:/ /.+?)"
(.+?) и (.*?) - любой текст
Что-бы выбрать "любой текст", нужно что-б этот паттерн был окружен текстом с обоих сторон, и было видно от куда до куда выбирать. По умолчанию этот паттерн выбирает любой текст кроме символа переноса строки, что-бы символ переноса строки подчинялся этому паттерну нужно использовать флаг DOTALL.
Отличие (.+?) от (.*?), "+" указывает на то что количество символов должно быть 1 или более, "*" - 0 или более. Например если попадет такой текст
'... <a href="">google</a>', то он не попадет в результат, т.к. у него href пустой, а в регексе условие ".+?" = 1 или более.
Примеры и заметки
Подмена функций на регексах