python Не жадное регулярное выражение, ищущее слишком много данных

Строка: '<td attr="0">str1</td><td attr="5">str2</td><td attr="7">str2</td><td attr="9">str4</td>'

Я хочу найти и получить только первый тег "td", который содержит текст: "str2". поэтому я попробовал два разных не жадных выражения, как показано ниже:

>>> mystring = '<td attr="0">str1</td><td attr="5">str2</td><td attr="7">str2</td><td attr="9">str4</td>'
>>> print re.search("(<td.*?str2.*?</td>)",mystring).group(1)
<td attr="0">str1</td><td attr="5">str2</td>
>>> print re.search(".*(<td.*?str2.*?</td>).*",mystring).group(1)
<td attr="7">str2</td>

Здесь я ожидал выхода как "<td attr="5">str2</td>", потому что я использовал не жадное выражение в регулярном выражении. Что здесь не так и как получить ожидаемый результат поиска?

Примечание: я не могу использовать html-парсер, потому что мой фактический набор данных не так сильно отформатирован для разбора xml

1 ответ

Решение

Использование [^>] вместо .:

>>> print re.search("(<td[^>]*?>str2.*?</td>)",mystring).group(1)
<td attr="5">str2</td>

( см. демо)

Или лучше используйте HTMLParser.

РЕДАКТИРОВАТЬ: Это регулярное выражение будет соответствовать даже под-теги:

(<td[^<]*?(?:<(?!td)[^<]*?)*str2.*?</td>)
Другие вопросы по тегам