Seite 1 von 2
Probleme mit RegEx...
Verfasst: Freitag 22. November 2002, 12:07
von x-herbert
Hi, ich möchte einen "alleinstehenden" Sting finden und benötige einen Tipp für RegEx. z.B. soll eMailNews oder eMail-News nicht gefunden werden (key=eMail)...
.....................
key = "eMail"
i = ".....bla bla XXXX ..." #siehe unten XXXX...
regkey = "\\b"+key+"\\b" # finde key allein
regex = re.compile(regkey)
result = regex.search(i)
if result:
print "find"
else:
print "find not"
.......................
Ergebnis
XXXX: print:
eMail find # o.k.
eMailNews find not
eMail_News find not
eMail-News find # upps !!!!!!!!!!!!!!!!
eMail*News find # upps !!!!!!!!!!!!!!!!
eMail?News find # upps !!!!!!!!!!!!!!!!
eMail#News find # upps !!!!!!!!!!!!!!!!
...usw.
Danke!
X-herbert
Re: Probleme mit RegEx...
Verfasst: Freitag 22. November 2002, 12:18
von Voges
Hallo!
x-herbert hat geschrieben:eMail_News find not
eMail-News find # upps !!!!!!!!!!!!!!!!
Das Verhalten ist ok. Aus der Doku zu
\b: "A word is defined as a sequence of alphanumeric or underscore characters". Der Bindestrich ist also kein Wortzeichen.
Jan
@voges
Verfasst: Freitag 22. November 2002, 13:17
von x-herbert
@voges
wie müsste dann der Code aussehen, dass z.B. eMail-News nicht gefunden werden??
x-herbert
Re: @voges
Verfasst: Freitag 22. November 2002, 13:44
von Voges
Hallo!
Erstmal 'ne Rückfrage: Was verstehst Du in Deinem konkreten Fall unter "alleinstehend"? Eingeschlossen nur von Whitespaces (zzgl. String-Anfang und -Ende)? Wie sieht es mit Satzzeichnen aus?
"eMail-News"
"eMail,News"
"eMail, News"
"eMail(News)"
"eMail!!!!!"
Welches eMail ist davon "alleinstehend"?
Wie Alex in der Python-NG auf Dein Posting so schön schrieb: "but before we delve into such complications it MIGHT be better for you to clarify exactly what you need" ;-)
Jan
@Voges
Verfasst: Freitag 22. November 2002, 14:01
von x-herbert
@Voges
mit "alleinstehend" meine ich, dass der String von einem Leerzeichen "umgeben sein darf, oder am Zeilen-Anfang/Ende...
Also bei Deinen Beispielen wäre nach "meiner Auffassung" keines der eMails "allein"
Gruss & Danke
x-herbert
Re: @Voges
Verfasst: Freitag 22. November 2002, 14:23
von Voges
x-herbert hat geschrieben:mit "alleinstehend" meine ich, dass der String von einem Leerzeichen "umgeben sein darf, oder am Zeilen-Anfang/Ende...
Dann würd' ich eine Lösung ohne Regexp favorisieren:
Code: Alles auswählen
text = "asdfadsf\neMail\tasdfasdf"
if "eMail" in text.split():
print "gefunden"
else:
print "nicht gefunden"
Jan
Nachtrag: Oops, Leerzeichen war nur gefragt. Dann muss es heißen: text.split(" ")
Verfasst: Freitag 22. November 2002, 15:01
von Milan
das funktioniert dann aber nur, wenn eMail auch als eMail geschrieben ist,bzw nur zwischen leerzeichen steht und nicht am Zeilenende, wie auch gewünscht... Wenn eMail als email geschrieben ist, funktioniert es nicht. Ich würde eher dein suchstring verändern:
Code: Alles auswählen
key="eMail"
regkey = "\s%s\s" % reduce(lambda x,y:x+"["+y+y.swapcase()+"]",key,"")
so wird zu jedem Buchtaben der eben andere (groß-->klein und umgekehrt gebildet) und das ganze in ein anderes Suchmuster eingebunden ("\s" heißst nach allem wie " \t\n\r\f\v" suchen, was ja das freistehend bedeuten würde.
@Milan
Verfasst: Freitag 22. November 2002, 15:21
von x-herbert
@Milan @Voges
Danke für die Infos...
... die Zeilen werde ich mal ausprobieren
Gruss x-herbert
Verfasst: Freitag 22. November 2002, 21:26
von hans
Also die erste Version von x-Herbert finde ich ganicht so schlecht. Muß doch eigentlich nur der Compilerbefehl umgestellt werden.
Code: Alles auswählen
regex = re.compile(regkey, re.IGNORECASE)
result = regex.search(i)
Quelle:
http://py-howto.sourceforge.net/regex/node11.html
Hans
@hans
Verfasst: Freitag 22. November 2002, 22:09
von x-herbert
@hans
sieht soweit nett aus.... als code-snipp:
import re
key = "eMail"
s = ".....bla bla eMail?xx ..."
regkey = "\\b"+key+"\\b"
regex = re.compile(regkey, re.IGNORECASE)
result = regex.search(s)
if result:
print "find"
else:
print "find not"
>>> find
hmmm....
Gruss x-herbert
@Milan
Verfasst: Freitag 22. November 2002, 22:17
von x-herbert
@Milan
Code: Alles auswählen
import re
key = "eMail"
s = ".....bla bla eMail-xx ..."
regkey = "\s%s\s" % reduce(lambda x,y:x+"["+y+y.swapcase()+"]",key,"")
regex = re.compile(regkey, re.IGNORECASE)
result = regex.search(s)
if result:
print "find"
else:
print "find not"
>>> find not
... scheint die Sachen abzudecken, die ich mir vorstelle.... Danke!
x-herbert
Re: @Milan
Verfasst: Freitag 22. November 2002, 22:28
von Voges
Hallo!
x-herbert hat geschrieben:... scheint die Sachen abzudecken, die ich mir vorstelle....
Bei
s = "eMail eMail" gibt es ein "find not", was sicherlich nicht erwünscht ist. Milans RegExp verlangt zwingend Whitespaces vorne und hinten.
Zudem: Auf r"\s[eE][Mm][aA][iI][lL]\s" nochmal re.IGNORECASE anzuwenden, ist doppeltgemoppelt. Mit IGNORECASE reicht r"\seMail\s".
Also, ich finde meine Lösung mit split() noch am besten (höhö). Wenn's aber unbedingt RegExps sein müssen:
Code: Alles auswählen
key = "eMail"
s = ".....bla bla eMail?xx ..."
regkey = r'(?:^|\s)'+key+r'(?:$|\s)'
regex = re.compile(regkey, re.IGNORECASE)
result = regex.search(s)
Jan
@Milan
Verfasst: Freitag 22. November 2002, 22:52
von x-herbert
@Milan
das "re.IGNORECASE" ist dann ja Quatsch...
entweder re.IGNORECASE oder die reduce/lambda-Version...
Gruss x-herbert
Re: @Milan
Verfasst: Freitag 22. November 2002, 23:02
von Voges
Hallo!
x-herbert hat geschrieben:das "re.IGNORECASE" ist dann ja Quatsch...
entweder re.IGNORECASE oder die reduce/lambda-Version...
Nur zur Klarstellung. Hans hatte re.IGNORECASE vorgeschlagen und zwar eben um Milans kompliziertes Konstrukt überflüssig zu machen. Das war vielleicht nicht klar geworden.
Jan
Re: @Milan
Verfasst: Freitag 22. November 2002, 23:21
von hans
Hi Voges
kann nicht behaupten dass dein Code richtig oder falsch ist, dafür müßte ich ihn ersteinmal verstehen
Ich habe dein Beispiel mal aufgelöst und komme zu folgendem Ergebnis:
Ist mir aber ehrlich gesagt immer noch unverständlich, obwohl ich etwas bewandert bin im Umgang mit grep, procmail und vi. Und RTFM hat mich auch nicht weitergebracht.
Hans
Re: @Milan
Verfasst: Freitag 22. November 2002, 23:57
von Voges
Hallo!
hans hat geschrieben:kann nicht behaupten dass dein Code richtig oder falsch ist, dafür müßte ich ihn ersteinmal verstehen :?
:-)
Also, das
?: ist in diesem konkreten Fall eigentlich überflüssig, hat für mich aber dokumentierenden Charakter.
regkey= r'(^|\s)eMail($|\s)'
Dann, denke ich, ist da schon klarer.
(^|\s) steht für
Stringanfang ODER Whitespace. Das ganze muss in Klammern stehen, damit klar ist, wo die beiden Alternativen anfangen und enden. Das gleiche Spiel nochmal für
($|\s).
Zum
?::
Im obigen Fall sind die runden Klammern nötig, um die ODER-Entscheidung zu ermöglichen. Andererseits nutzt man aber auch runde Klammern, um innerhalb von Regexps sogenannte Gruppen zu bilden.
Beispiel 1
Ich will eine Liste mit den Zahlen in den geschw. Klammern, die Klammern will ich aber nicht mit in der Liste haben:
s = "{4325} 23 {2343} 23 {4} 23 {}"
print re.findall(r'{(\d+)}',s) # --> ['4325','2343','4']
Beispiel 2
Ich will eine Liste mit den Zahlen in den geschw. Klammern und den Zahlen zw. "###"-Paaren:
s = "{4325} {2343} 34 ###4### 23"
print re.findall(r'(?:###|{)(\d+)(?:###|})',s) # --> ['4325', '2343', '4']
Das
?: ist nur ein Schalter, der verhindert, dass das Runde-Klammer-Paar zur Gruppierung herangezogen wird. Ohne diese
?: Schalter sähe die Liste so aus:
[('{', '4325', '}'), ('{', '2343', '}'), ('###', '4', '###')]
Jan
Verfasst: Samstag 23. November 2002, 10:12
von Milan
danke Voges, den Fehler hab ich nich gesehn... aber ich musste trotz deiner Erklärung noch ein paar mal in der Syntax nachschlagen, eh ich's kapiert hatte...
Verfasst: Samstag 23. November 2002, 11:04
von hans
@Voges
Jetzt etwas verständlicher
Ich muß da wohl noch etwas üben
Ich bin aber auch etwas verwirrt. Ich dachte, dass re.search() immer nach ganzen Worten sucht, wobei ein Wort immer am Zeilenanfang steht oder mit Whitespace beginnt und immer am Zeilenende, mit Null oder Whitespace endet. (Kann sein, dass ich nicht alle Begrenzer genannt habe).
Wenn re.search() nur die reine Zeichenkombination sucht, kann ich dein Beispiel nachvollziehen. Wenn re.search() jedoch wortweise vergleicht, ist deine Suchfunktion etwas überfrachtet und würde nur Sinn machen, wenn man weitere Feldtrenner definieren will.
Hans
*
Verfasst: Dienstag 26. November 2002, 21:59
von x-herbert
... habe noch was im Netz gefunden...
Code: Alles auswählen
DecodeUnicodeString = lambda x: codecs.latin_1_encode(x)[0]
gruss x-herbert
Re: *
Verfasst: Dienstag 26. November 2002, 22:18
von Voges
Hallo!
x-herbert hat geschrieben:... habe noch was im Netz gefunden...
Ich steh' etwas auf dem Schlauch. In welchem Zusammenhang steht das zum bisher Erörterten?
Jan