Python re.sub использует не жадный режим (. *?) С концом строки ($), он становится жадным! - PullRequest
6 голосов
/ 25 ноября 2010

Код:

str = '<br><br />A<br />B'
print(re.sub(r'<br.*?>\w$', '', str))

Ожидается возвращение <br><br />A, но возвращается пустая строка ''!

Любое предложение?

Ответы [ 2 ]

6 голосов
/ 25 ноября 2010

Жадность работает слева направо, но не иначе. Это в основном означает «не совпадать, если вы не смогли сопоставить». Вот что происходит:

  1. Движок регулярных выражений соответствует <br в начале строки.
  2. .*? пока игнорируется, это ленивый.
  3. Попробуйте сопоставить >, и все получится.
  4. Попробуйте сопоставить \w и не получится. Теперь это интересно - двигатель начинает движение назад и видит правило .*?. В этом случае . может соответствовать первому >, поэтому есть надежда на это совпадение.
  5. Это продолжается до тех пор, пока регулярное выражение не достигнет косой черты. Тогда >\w может совпадать, но $ не удается. Опять же, двигатель возвращается к ленивому правилу .* и продолжает сопоставляться, пока не совпадет с <br><br />A<br />B

К счастью, есть простое решение: заменив <br[^>]*>\w$, вы не разрешите сопоставление за пределами ваших тегов, поэтому оно должно заменить последнее вхождение.
Строго говоря, это плохо работает для HTML, поскольку атрибуты тега могут содержать > символов, но я предполагаю, что это всего лишь пример.

1 голос
/ 25 ноября 2010

Жадность не начнется позже, как это.Он соответствует первому <br и будет не жадно совпадать с остальными, которые на самом деле должны идти до конца строки, потому что вы указываете $.

Чтобы заставить его работать так, как вы хотели,используйте

/<br[^<]*?>\w$/

, но обычно для анализа HTML не рекомендуется использовать регулярное выражение, так как в значении некоторых атрибутов может быть < или >.

...