Найти - Пользователи
Полная версия: Проблема с регуляркой
Начало » Python для новичков » Проблема с регуляркой
1
Cyxapeff
Есть регулярное выражение:

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 раза регулярка отработала) и отжирает всё процессорное время. Я даже примерно понимаю из-за чего это получается. Но как бороть?

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

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

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

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

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

..bw
Ferroman
.* сожрёт все, а .*? - все до совпадения с следующем паттерном.
Cyxapeff
Именно. Если есть строка:

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

html5lib посмотрю, но всё таки хочется узнать как можно починить регулярку. Пригодится.
Yurietc
Регулярками можно распарсить практически любой текст. Но большая регулярка, даже правильно написанная, будет сильно тормозить. Регексп в первом посте у меня просто не работает с указанным сайтом.
HTML - имеет свою структуру, и это надо использовать при парсинге. Попробуй сначала выделить нужные части документа с помощью того же html5lib или Beautiful Soup. А потом к небольшим кускам текста применяй маленькие регекспы. Сведи к минимуму использование .* даже не жадного, где можно, используй (?:something) вместо (something)…
Здесь хорошая статья по регекспам.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB