2010-11-25 1 views
5

Code:

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

Es wird erwartet, <br><br />A zurück, aber es gibt einen leeren String ''!

Irgendwelche Vorschläge?

+2

Bitte verwenden Sie niemals 'str' als Variablenname. –

+0

Danke an Ihren Vorschlag. –

+1

Äh ... hey ... Sie analysieren HTML nicht mit regulären Ausdrücken, oder? – detly

Antwort

6

Gierigkeit funktioniert von links nach rechts, aber nicht anders. Es bedeutet im Grunde "nicht übereinstimmen, wenn Sie nicht übereinstimmen". Hier ist was los:

  1. Die Regex-Engine entspricht <br zu Beginn der Zeichenfolge.
  2. .*? wird für jetzt ignoriert, es ist faul.
  3. Versuchen Sie, > zu entsprechen, und ist erfolgreich.
  4. Versuchen Sie, \w übereinzustimmen und schlägt fehl. Jetzt ist es interessant - die Engine startet Backtracking und sieht die .*? Regel. In diesem Fall kann . die erste > übereinstimmen, also gibt es noch Hoffnung für dieses Spiel.
  5. Dies passiert, bis die Regex den Schrägstrich erreicht. Dann kann >\w übereinstimmen, aber $ schlägt fehl. Auch hier kommt der Motor auf die faulen .* Regel zurück, und Matching hält, bis es zum Glück <br><br />A<br />B

paßt, gibt es eine einfache Lösung: Durch <br[^>]*>\w$ ersetzen Sie dies nicht tun passende außerhalb Ihrer Tags erlauben, so Es sollte das letzte Vorkommen ersetzen.
Genau genommen funktioniert dies nicht gut für HTML, weil Tag-Attribute > Zeichen enthalten können, aber ich nehme an, es ist nur ein Beispiel.

1

Die Non-Gierigkeit wird später nicht so beginnen. Es entspricht der ersten <br und wird nicht gierig mit dem Rest übereinstimmen, der tatsächlich an das Ende der Zeichenfolge gehen muss, weil Sie die $ angeben.

Um es die Art und Weise funktioniert Sie verwenden

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

aber in der Regel ist es nicht zu verwenden regex empfohlen wollte HTML zu analysieren, da einige Wert des Attributs < oder > darin haben kann.