RegEx: doppeltes Wort löschen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Raggi
User
Beiträge: 12
Registriert: Donnerstag 6. März 2008, 23:29

Donnerstag 6. März 2008, 23:34

Hallo,

wie kann man über einen regulären Ausdruck ein doppeltes Wort löschen? Auf diese Weise bekomme ich nur die doppelten angezeigt

Code: Alles auswählen

>>> p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')
>>> p.search('Paris in the the spring').group()
'the the'
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Freitag 7. März 2008, 00:01

öhm...erstelle eine zweite Gruppe, die auf den Inhalt der ersten Gruppe matcht und ersetze diese dann durch nichts.

Code: Alles auswählen

In [30]: from re import X, M, S
In [31]: s
Out[31]: u'Ich bin bin K\xe4se!'

In [32]: re.sub(r"(?P<word>\b\w+)\s+(?P<double>(?P=word))", r'\1', s, X|M|S)
Out[32]: u'Ich bin K\xe4se!'
(Den Namen hab ich nur gegeben, ums klarer zu machen, der ist unnötig...)
Raggi
User
Beiträge: 12
Registriert: Donnerstag 6. März 2008, 23:29

Freitag 7. März 2008, 00:16

großartig! AUf die Idee kam ich gar nicht.
Funktioniert - besten Dank
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 7. März 2008, 08:18

Also ich würde den import nicht so nutzten. Entweder re.X, re.M, re.S oder direkt in der RE hinterlegen, ich glaube das geht so: r"(?P<word>\b\w+)\s+(?P<double>(?P=word))(?xms)"

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Freitag 7. März 2008, 12:14

Ah, danke!

Ich hab in der Doku nicht gefunden, wie es geht, muss es wohl überlesen haben...

Ich wollte mir für RegExp schon zusamen mit functool.partial nen ordentlich compile() mit den richtigen Flags in die Toolbox packen :D
Raggi
User
Beiträge: 12
Registriert: Donnerstag 6. März 2008, 23:29

Freitag 7. März 2008, 15:05

mein Wert sieht so aus:
1111*Risikotragung|1112*Garantie|1113*Verbraucherschutz:Warenkauf|1112*Garantie

mit dem Code von audax werden aber nur doppelte Wörter, die hintereinander stehen und mit Leerzeichen getrennt sind, gelöscht

Wisst Ihr, wie man doppelte Wörter in unbekannter Reihenfolge ohne Leerzeichen löscht?
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Freitag 7. März 2008, 15:18

Raggi hat geschrieben:Wisst Ihr, wie man doppelte Wörter in unbekannter Reihenfolge ohne Leerzeichen löscht?
Wild geraten, aber bekommst du nicht vielleicht das, was du willst, wenn du alle Wörter suchst, und die dann in ein Set schmeist, so dass du keine Doppelten mehr hast? Oder gehts dir auch um die Reihenfolge und die "nichtwörter" im Text?
BlackJack

Freitag 7. März 2008, 15:20

@Raggi: Am besten nicht mit einem regulären Ausdruck. Falls die Reihenfolge der einzelnen Daten im Ergebnis egal ist:

Code: Alles auswählen

print '|'.join(set(data.split('|')))
Falls die Reihenfolge erhalten bleiben soll:

Code: Alles auswählen

def delete_doublettes(line, separator='|'):
    seen = set()
    result = list()
    for item in line.split(separator):
        if item not in seen:
            seen.add(item)
            result.append(item)
    return separator.join(result)
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Freitag 7. März 2008, 15:32

Code: Alles auswählen

words = re.findall(r'(\w+)\s+(?xms)', foobar, re.UNICODE)
for word in words:
    how_often = len(re.findall(word, s))
    if how_often > 1:
        s = re.sub(word, '', s, how_often-1)
€dit:
Das '\s' ersetzt man dann natürlich durch seinen eigenen seperator.
Und das '\w' durch...naja, was auch immer man als Wort erkannt haben will.
Raggi
User
Beiträge: 12
Registriert: Donnerstag 6. März 2008, 23:29

Freitag 7. März 2008, 15:39

NameError: global name 'set' is not defined

"Set" wurde wohl in Python2.4 eingeführt.
Ich muss aber 2.3 nehmen

Gibt es noch einen anderen Weg?
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Freitag 7. März 2008, 15:45

In Py-2.3 bekommt man das einfach mit

Code: Alles auswählen

from sets import Set as set
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Freitag 7. März 2008, 15:47

Natürlich gibt es einen anderen Weg. Es gibt hunderte.

Code: Alles auswählen

splitted = data.split('|')
normalized = []
for token in splitted:
    if not token in normalized:
        normalized.append(token)
data = '|'.join(normalized)
Das sollte verständlich genug sein...
Raggi
User
Beiträge: 12
Registriert: Donnerstag 6. März 2008, 23:29

Freitag 7. März 2008, 17:56

Riesiges DANKE an Euch alle!

habe mich nun für

Code: Alles auswählen

print '|'.join(set(data.split('|')))
entschieden. Unglaublich, wie einfach Python ist, wenn man es kennt!
Antworten