Seite 1 von 1

Reguläre Ausdrücke - Problem mit re.sub

Verfasst: Montag 12. März 2007, 17:51
von okasankar
Hallo liebe Python-Entwickler :)

Ich schreibe noch nicht solange in Python und hab auch reguläre Ausdrücke noch nicht so oft benutzt.

Ich habe folgendes Problem. In meinem Programm soll folgende Methode mir zu einem gegebenen Patternstring im String alle Teilstrings finden die auf das Pattern passen und mit den Markierungstoken vorn und hinten ersetzen.

Code: Alles auswählen

def mark(pattern, string, startMarkToken, endMarkToken):
    """Marks all substrings in the string which matches the pattern.
    """
    #look for matches
    matches = re.findall(pattern, string, re.I|re.L|re.U) #ignore case
    #create a set of the matches to avoid double entries
    matches = set(matches)
    #mark each match in the string with the predefined markTokens
    for match in matches:
        string = re.sub(match, startMarkToken+match+endMarkToken, string)
    #return marked string
    return string
Das funktioniert soweit ganz gut. Ein Problem bekomme ich in dem Moment, wo zum Beispiel mein "match" Objekt in Zeile 10 zum Beispiel Klammern enthält etwa: "Hallo (Mein) Lieber". Dann funktioniert nämlich das Ersetzen mit re.sub nicht mehr auch wenn diese Zeichenfolge in meinem String vorkommt.

Woran kann das liegen? Wie könnte ich das Problem lösen?

Vielen Dank im Voraus,
Okasankar :)

Verfasst: Montag 12. März 2007, 18:42
von BlackJack
Das liegt daran, dass die Klammern in regulären Ausdrücken eine besondere Bedeutung haben.

Kann es sein, dass man Dein Anliegen auch so formulieren kann (ungetestet):

Code: Alles auswählen

def mark(pattern, string, start_marker, end_marker):
    regex = re.compile(pattern, re.IGNORECASE | re.LOCALE | re.UNICODE)
    return regex.sub(re.escape(start_marker) + r'\0' + re.escape(end_marker),
                     string)

Verfasst: Dienstag 13. März 2007, 01:24
von PmanX
Brauchen wir da re?

Code: Alles auswählen

>>> s1 = 'hell'
>>> s2 = '(blau)'
>>> 'rot (blau) und gruen, rot vllt (blau)'.replace( s2, s1 + s2 + s1)
'rot hell(blau)hell und gruen, rot vllt hell(blau)hell'

# Edit:
# oder doch mit?
import re

>>> s1 = '(blue)'
>>> such = re.escape(s1)
>>> s2 = '(blue) socks and red shoes or (blue)'
>>> cre = re.compile('(' + such + ')')
>>> cre.subn( r'--\1--', s2)
('--(blue)-- socks and red shoes or --(blue)--', 2)
Schreibt sich grauenhaft!

Verfasst: Dienstag 13. März 2007, 08:25
von okasankar
Vielen Dank für die schnellen Antworten. :)

Code: Alles auswählen

def mark(pattern, string, start_marker, end_marker):
    regex = re.compile(pattern, re.IGNORECASE | re.LOCALE | re.UNICODE)
    return regex.sub(re.escape(start_marker) + r'\0' + re.escape(end_marker),
                     string)
Das ging leider irgendwie nicht. :/ Aus reinem Wissensdurst das'\0' ist da, um an eine Gruppe von einen Match zu kommen? :)

Hab jetzt die re.sub Zeile durch den string replace ersetzt und es funktioniert alles sehr gut. :)

Vielen Dank noch mal euch beiden. :)

Verfasst: Dienstag 13. März 2007, 08:43
von BlackJack
r'\0' ist der ganze "Match", mit r'\1 \2 \3 ...' kommt man an die Gruppen.