Можно ли сделать так, чтобы найти минимальное совпадение при использовании жадных символов? - PullRequest
4 голосов
/ 15 сентября 2009

Отказ от ответственности: я не эксперт по регулярным выражениям.

Я использую модуль Python re для сопоставления регулярных выражений многих htm-файлов. Один из шаблонов выглядит примерно так:

<bla><blabla>87765.*</blabla><bla>

Проблема, с которой я столкнулся, состоит в том, что вместо того, чтобы найти все (скажем) пять вхождений шаблона, он найдет только одно. Поскольку он объединяет все вхождения в один, используя часть <bla><blabla>87765 первого вхождения и часть </blabla><bla> последнего вхождения на странице.

Можно ли как-нибудь сказать, чтобы найти наименьшее совпадение?

Ответы [ 4 ]

13 голосов
/ 15 сентября 2009

В шаблоне можно использовать неохотный квалификатор (для получения более подробной информации см. Документацию python для операторов *?, +? и ??):

<bla><blabla>87765.*?</blabla><bla>

Или исключить < из возможных совпавших символов:

<bla><blabla>87765[^<]*</blabla><bla>

только , если между <blabla> и </blabla>.

нет дочерних тегов.
2 голосов
/ 15 сентября 2009

Модуль Python re поддерживает несжатое сопоставление. Вы просто добавляете ? в конец шаблона подстановки, например .*?. Вы можете узнать больше на этом HOWTO .

1 голос
/ 15 сентября 2009
I believe the regex
<bla><blabla>87765.*?</blabla><bla>
can produce catastrophic backtracking.

Instead, use:
<bla><blabla>87765[^<]*</blabla><bla>

Using atomic grouping (I'm not sure Python supports this), 
the above regex becomes 
<bla><blabla>(?>(.*?<))/blabla><bla>

Все между (?> ...) обрабатывается как один токен механизмом регулярных выражений, как только механизм регулярных выражений покидает группу. Поскольку вся группа представляет собой один токен, откат не может быть выполнен после того, как механизм регулярных выражений найдет соответствие для группы. Если требуется возврат, движок должен вернуться к токену регулярного выражения перед группой (каретка в нашем примере). Если перед группой нет токена, регулярное выражение должно повторить все регулярное выражение в следующей позиции в строке. Обратите внимание, что мне нужно было включить «<» в группу, чтобы обеспечить атомарность. Достаточно близко. </p>

0 голосов
/ 15 сентября 2009

Гм ... есть способ указать re, чтобы найти наименьшее совпадение, и именно с помощью не жадных квантификаторов.

<bla><blabla>87765.*?</blabla><bla>

Не могу представить, почему вы захотите сделать это, используя жадные квантификаторы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...