Zeichen ignorieren bei find()

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
mushroom
User
Beiträge: 58
Registriert: Sonntag 21. November 2010, 12:32

Hallo,

ich durchsuche eine Datei nach einem bestimmten string 'abc' mittels find(). Nun kommt es vor, daß in der Datei der string durch einen Zeilenumbruch getrennt ist, also 'ab\nc'. Die Datei ist zeilenweise aufgebaut.
Um den kompletten String zu finden, könnte man die Zeilenumbrüche alle ersetzen (durch nichts :-)). Da die Datei ziemlich groß ist (bis zu 200000 Zeilen in der Regel), stelle ich mir vor, daß dies recht zeitintensiv ist.
Daher meine Frage: Gibt es eine Möglichkeit bei der Suche bestimmte Zeichen einfach zu ignorieren?

Grüße
mushroom
BlackJack

@mushroom: Das sieht nach einer Aufgabe für das `re`-Modul aus.
mushroom
User
Beiträge: 58
Registriert: Sonntag 21. November 2010, 12:32

Ei ei, hatte das re-Modul bisher immer absichtlich ignoriert, da ich es teils als ziemlich kompliziert ansah. Aber da werde ich mich dann wohl mal durchbeißen müssen. Danke für den Hinweis.
mushroom
User
Beiträge: 58
Registriert: Sonntag 21. November 2010, 12:32

Habe mich mal ein wenig reingelesen in das re-Modul. Im konkreten geht es darum in einer Datei einen bestimmten String zu finden und zwar '\\NImag='. Dabei kann - muß aber nicht- dieser String, wie bereits oben erwähnt durch einen Zeilenumbruch '\n' unterbrochen sein. Ich habe jetzt folgenden Code

Code: Alles auswählen

import re

string = '\\\\Nab=c\\\n\\NImag=3\\\\Na=7'
print string
c =  re.search(r'\.*=', string, re.S)
print string[c.end()]
Den string habe ich dabei etwas erweitert um falsche Suchergebnisse auszuschließen. So wie jetzt gesucht wird, druckt er mir aber das 'c' statt der gewünschten '3' aus. Daraufhin hatte ich mir überlegt, die Zahl der der zwischen '\' und '=' vorkommenden Zeichen zu begrenzen:

Code: Alles auswählen

c =  re.search(r'\.*{6,7}=', string, re.S)
also mindestens 6 Zeichen '\NImag' und maximal 7 Zeichen '\N\nImag' beispielsweise, wobei '\n' ein Zeichen ist, wenn ich das richtig interpretiere (!?). Viel geschrieben, Konsequenz ist, daß es mit den geschweiften Klammern leider nicht funktioniert. Erhalte den Fehler

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\Markus\Pythonprojekte\Gaussian\retest.py", line 13, in <module>
    c =  re.search(r'\.*{6,7}=', string, re.S)
  File "C:\Python26\lib\re.py", line 142, in search
    return _compile(pattern, flags).search(string)
  File "C:\Python26\lib\re.py", line 245, in _compile
    raise error, v # invalid expression
sre_constants.error: multiple repeat
den ich allerdings nicht verstehe.

Grüße
mushroom
BlackJack

@mushroom: '*' bedeutet beliebig oft (inklusive gar nicht!) und '{6,7}' bedeutet 6 oder 7 mal. Und `re` weiss nun nicht was es damit anfangen soll wenn Du das *beides* auf den '.' anwendest.

Was Du haben möchtest ist ja letztendlich r'\NImag' wobei zwischen jedem dieser Zeichen optional ein '\n' stehen könnte. Ein '\n' oder "nichts" wäre als regulärer Ausdruck r'\n?'. Wenn man das jetzt zwischen alle Zeichen setzt:

Code: Alles auswählen

In [226]: string = '\\\\Nab=c\\\n\\NIm\nag=3\\\\Na=7'

In [227]: re.findall(r'\\\n?N\n?I\n?m\n?a\n?g', string)
Out[227]: ['\\NIm\nag']
mushroom
User
Beiträge: 58
Registriert: Sonntag 21. November 2010, 12:32

Danke BlackJack,

habs noch ein wenig auf mein Problem angepasst, aber so funktioniert es jetzt. Das mit der Doppeldeutigkeit bezüglich * und {} ist mir auch gerade aufgefallen.

Grüße
mushroom
Antworten