Могу ли я иметь нежадное регулярное выражение с dotall?

Я хотел бы сопоставить dotall и нежадный. Вот что у меня есть:

img(.*?)(onmouseover)+?(.*?)a

Тем не менее, это не нежадность. Эти данные не совпадают, как я ожидал:

<img src="icon_siteItem.gif" alt="siteItem" title="A version of this resource is available on siteItem" border="0"></a><br><br></td><td rowspan="4" width="20"></td></tr><tr><td>An activity in which students find other more specific adjectives to 
describe a range of nouns, followed by writing a postcard to describe a 
nice holiday without using the word 'nice'.</td></tr><tr><td>From the resource collection: <a href="http://www.siteItem.co.uk/index.asp?CurrMenu=searchresults&amp;tag=326" title="Resources to help work">Drafting </a></td></tr><tr><td><abbr style="border-bottom:0px" title="Key Stage 3">thing</abbr> | <abbr style="border-bottom:0px" title="Key Stage 4">hello</abbr> | <abbr style="border-bottom:0px" title="Resources">Skills</abbr></td></tr></tbody></table></div></div></td></tr><tr><td><div style="padding-left: 30px"><div><table style="" bgcolor="#DFE7EE" border="0" cellpadding="0" cellspacing="5" width="100%"><tbody><tr valign="top"><td rowspan="4" width="60"><a href="javascript:requiresLevel0(350,350);"><img name="/attachments/3700.pdf" onmouseover="ChangeImageOnRollover(this,'/application/files/images/attach_icons/rollover_pdf.gif')" onmouseout="ChangeImageOnRollover(this,'/application/files/images/attach_icons/small_pdf.gif')" src="small_pdf.gif" alt="Download Recognising and avoiding ambiguity in PDF format" title="Download in PDF format" style="vertical-align: middle;" border="0"></a><br>790.0 k<br>

и я не могу понять, почему.

Я думаю, что я утверждаю в приведенном выше регулярном выражении:

начните с «img», затем разрешите 0 или более любых символов, включая новую строку, затем найдите хотя бы 1 «onmouseover», затем разрешите 0 или более любых символов, включая новую строку, затем «a»

Почему это не работает, как я ожидал?

КЛЮЧЕВОЙ МОМЕНТ: dotall должен быть включен


person rich tier    schedule 29.02.2012    source источник
comment
Кажется, это работает отлично. Я получаю совпадение на img name="/attachments/3700.pdf" onmouseover="Cha   -  person Jørgen R    schedule 01.03.2012
comment
@jurgemaister, у вас включен dotall?   -  person rich tier    schedule 01.03.2012
comment
Нет, не знаю. Видимо, я недостаточно внимательно прочитал вопрос. В этом случае он соответствует всему, от второго символа до точки, о которой я упоминал выше. Что также было бы ожидаемо.   -  person Jørgen R    schedule 01.03.2012
comment
@jurgemaister мы все делаем ошибки. Я сделал один раз!   -  person rich tier    schedule 01.03.2012
comment
Нежадное сопоставление означает, что оно остановится на первом возможном символе. Это не значит, что он начнется с последнего возможного символа, которого вы, похоже, ожидаете.   -  person interjay    schedule 01.03.2012
comment
Чего вы на самом деле пытаетесь добиться этим? Было бы легче предлагать улучшения, если бы мы знали цель и примеры результатов...   -  person Karl Barker    schedule 01.03.2012


Ответы (2)


Это не жадность. Это ваше понимание нежадности неверно.

Регулярное выражение всегда пытается найти соответствие.

Позвольте мне показать упрощенный пример того, что на самом деле означает «нежадный» (как было предложено в комментарии):

re.findall(r'a*?bc*?', 'aabcc', re.DOTALL)

Это будет соответствовать:

  • как можно меньше повторений «а» (в данном случае 2)
  • за которым следует буква «б»
  • и как можно меньше повторений 'c' (в данном случае 0)

поэтому единственное совпадение - 'aab'.

И в заключение:

Не используйте регулярное выражение для анализа HTML. Есть библиотеки, которые были сделаны для работы. re не входит в их число.

person stranac    schedule 29.02.2012
comment
в качестве упрощенного примера используйте re.findall(r'a*?bc*?', 'aabcc', re.DOTALL) - person wim; 01.03.2012
comment
Почему ваш пример просто не возвращает b? Почему ему может сойти с рук совпадение 'c' ноль раз, а 'a' должно соответствовать дважды? - person duozmo; 22.03.2014
comment
Нашел ответ на свой вопрос: stackoverflow.com/questions/16633315/ - person duozmo; 22.03.2014
comment
plus1 за ваш вывод Не используйте регулярное выражение для анализа html. Я именно это и пытался сделать. - person positron; 18.09.2015
comment
Вероятно, вам следует добавить два примера библиотек, которые можно использовать для анализа HTML. (Я знаю, что красивый суп работает хорошо). - person Martin Thoma; 12.10.2015

Во-первых, ваше регулярное выражение выглядит немного странно: вы говорите, что соответствует img, затем любое количество символов, onmouseover по крайней мере один раз, но, возможно, повторяется (например, onmouseoveronmouseoveronmouseover), за которым следует любое количество символов, за которым следует a.

Это должно совпадать от img src="icon_ до onmouseover="Cha. Возможно, это не то, что вы хотите, но это то, о чем вы просили.

Во-вторых, и это значительно важнее:

НЕ ИСПОЛЬЗУЙТЕ ОБЫЧНЫЕ ВЫРАЖЕНИЯ ДЛЯ АНАЛИЗА HTML.

А если вы не поняли с первого раза, повторю курсивом:

НЕ ИСПОЛЬЗУЙТЕ ОБЫЧНЫЕ ВЫРАЖЕНИЯ ДЛЯ АНАЛИЗА HTML.

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

Вы не можете анализировать [X]HTML с помощью регулярного выражения

person tylerl    schedule 29.02.2012
comment
@tchirst: То, что вы создали в сообщении, на которое вы ссылаетесь, представляет собой парсер HTML, который использует регулярные выражения для создания своего лексера. Это умно, это мощно. Но чем оно не является, так это регулярным выражением, описывающим HTML, потому что состояние (глубина) должно поддерживаться отдельно. Он полезен в качестве сторонней библиотеки синтаксического анализа, но весь смысл в том, чтобы отговорить новичков от синтаксического анализа HTML с помощью регулярных выражений, состоит в том, чтобы побудить их использовать проверенные, специально созданные библиотеки синтаксических анализаторов. HTML гораздо сложнее, чем можно безопасно зафиксировать в однострочном регулярном выражении, написанном новичком. (Кроме того, мне понравились ваши книги) - person tylerl; 01.03.2012