Уведомления

Группа в Telegram: @pythonsu

#1 Май 18, 2009 20:04:23

Cyxapeff
От:
Зарегистрирован: 2006-08-17
Сообщения: 148
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с регуляркой

Есть регулярное выражение:

p = re.compile(r'<table.*?class="mb20".*?>.*?<td.*?>.*?<a.*?href="(?P<url>.*?)".*?src="(?P<img>.*?)".*?alt="(?P<title>.*?)".*?</td>.*?/h3>.*?<br.*?>(?P<genre>.*?)(<br|&nbsp;).*?var params = {(?P<params>.*?)}', re.DOTALL)
Им разбираю странички при помощи search, пока оно не вернёт None. А текст соответственно обрезаю.

search = p.search(content)
while not search is None:
...
content = content[search.span()[1]:]
search = p.search(content)
И вроде всё очень хорошо, пока я не нарвался на страничку http://topas.imhonet.ru/rates/all/?type=3&page=8 (т.к контент не статичный, то вот отдельно исходник: http://dumpz.org/8762/ )

Питон зависает на p.search (после того, как 2 раза регулярка отработала) и отжирает всё процессорное время. Я даже примерно понимаю из-за чего это получается. Но как бороть?

Спасибо.



Отредактировано (Май 19, 2009 10:12:06)

Офлайн

#2 Май 19, 2009 07:52:45

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

Проблема с регуляркой

Во-первых, что обозначает первый Вопрос и все Вопросы после Звезд? Каков их сакральный смысл?
Во-вторых. Имеет смысл описать задачу, которую у тебя решает регулярка, не все испытывают интерес докопаться до него читая “кривую” регулярку.
В-третьих. Ради прикола, не пытался проверять, что у тебя возвращает .span()? Ты учел, что значения могут быть отрицательными? Ну и стоит проанализировать, как выглядит последний content перед тем как процедура виснет в долгих раздумиях.

..bw



Офлайн

#3 Май 19, 2009 10:11:23

Cyxapeff
От:
Зарегистрирован: 2006-08-17
Сообщения: 148
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с регуляркой

1) Ээм. В смысле конструкция “.*?”? Это не жадный поиск. Вроде всю жизнь он так обозначался… А первый это случайно ) Игрался с выражение, видимо не стёр. Вообще он ни на что не влияет.
2) Регулярка выдирает информацию о фильмах со странички. Что именно выдирает понятно по названиям переменных: название, урл, картинку, жанр и params это json.
3) Пробовал, это первое, что пришло в голову. Значения нормальные.
4) Последний content выглядит вот так http://dumpz.org/8780/ Конечно я на него посмотрел. Поэтому я и примерно понимаю из-за чего не работает. Там много кода почти подходящего под регулярное выражение. Но как бороться - не знаю. findall возвращает то что надо, но в виде списка, а не словаря, что очень неудобно, поэтому его использовать совсем не хочется.



Офлайн

#4 Май 19, 2009 11:14:02

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

Проблема с регуляркой

Всё равно не вижу разницы между .* и .*?, хотя я могу чего-то не знать в работе регулярок.

Собственно HTML я никогда регулярками не разбираю, да и вообще их использую так что бы выражения получались максимально простыми. HTML я пропускаю через html5lib, а дальше хожу по нему силами xpath. Попробуй поступить так-же. Как минимум, в таком случае, будет проще обрабатывать ошибки.

В поиске регуляркой по тексту я не использую урезание самого текста для продолжения поиска с текущей позиции, а указываю с какой позиции продолжать искать (.search(content, pos)). Возможно такой вариант использования регулярок поспособствует выявлению ошибки.

Ну и не сталкивался я с зависанием поиска, это что-то очень интересное.

..bw



Офлайн

#5 Май 19, 2009 13:19:52

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Проблема с регуляркой

.* сожрёт все, а .*? - все до совпадения с следующем паттерном.

Офлайн

#6 Май 19, 2009 15:08:10

Cyxapeff
От:
Зарегистрирован: 2006-08-17
Сообщения: 148
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с регуляркой

Именно. Если есть строка:

<tag>blablabla</tag><othertag>bla-bla-bla</othertag>
То >(.*)< вернёт blablabla</tag><othertag>bla-bla-bla
А >(.*?)< просто blablabla

html5lib посмотрю, но всё таки хочется узнать как можно починить регулярку. Пригодится.



Офлайн

#7 Май 19, 2009 15:36:46

Yurietc
От:
Зарегистрирован: 2007-07-18
Сообщения: 112
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с регуляркой

Регулярками можно распарсить практически любой текст. Но большая регулярка, даже правильно написанная, будет сильно тормозить. Регексп в первом посте у меня просто не работает с указанным сайтом.
HTML - имеет свою структуру, и это надо использовать при парсинге. Попробуй сначала выделить нужные части документа с помощью того же html5lib или Beautiful Soup. А потом к небольшим кускам текста применяй маленькие регекспы. Сведи к минимуму использование .* даже не жадного, где можно, используй (?:something) вместо (something)…
Здесь хорошая статья по регекспам.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version