Seite 1 von 1
Hilfe bei regular expression
Verfasst: Dienstag 6. Juni 2006, 17:02
von Mati
Hallo,
ich habe Probleme eine regex zu basteln:
folgender string:
st = "...TEXXXXT\n 2.0 4.5 0.1 8.9\n CONSTANT 111 222 333 \nENDE\nWeiterer Text...."
dieses bruchstück taucht sehr oft vor in einem gewaltigen string. Oben ist nur ein Ausschnitt gezeigt wobei aber die wichtige stelle herausgeschrieben ist.
Schlüsselwort ist CONSTANT. Die Zahlen die vor CONSTANT kommen und die Zahlen danach möchte ich herauspfrimeln und in genau ein Multitupel fassen
-> (2.0, 4.5, 0.1, 8.9, 111, 222, 333)
das ergebnis wären also viele Multitupel die immer Zahlen beinhalten die sich "um das wort CONSTANT befinden"
Bisheriger Ansatz:
Code: Alles auswählen
rgx = re.compile(r'[0-9]+.[0-9]*(\s*)]*CONSTANT(.*?)(?=ENDE)' , re.DOTALL | re.IGNORECASE)
wäre nett wenn mir jemand helfen könnte wie ich auf effizienteste weise einfach diese zusammengehörigen werte bekommen könnte DANKE
Verfasst: Mittwoch 7. Juni 2006, 21:16
von BlackJack
Mati hat geschrieben:wäre nett wenn mir jemand helfen könnte wie ich auf effizienteste weise einfach diese zusammengehörigen werte bekommen könnte DANKE
Also ich finde
PyParsing oft einfacher als reguläre Ausdrücke. Sowohl beim Schreiben als auch beim Verstehen, falls man sich den Quelltext in einem Jahr nochmal anschaut.
Code: Alles auswählen
from pyparsing import CaselessKeyword, OneOrMore, Regex, Suppress
source = """\
...TEXXXXT
2.0 4.5 0.1 8.9
CONSTANT 111 222 333
ENDE
Weiterer Text....
5 6 7
CoNsTaNt 42
4711 23
BlaH
"""
number = Regex(r'[0-9]+(\.[0-9]+)?')
constant = Suppress(CaselessKeyword('CONSTANT'))
grammar = OneOrMore(number) + constant + OneOrMore(number)
print [tuple(map(float, match[0])) for match in grammar.scanString(source)]
Das Ergebnis ist:
Code: Alles auswählen
[(2.0, 4.5, 0.10000000000000001, 8.9000000000000004, 111.0, 222.0, 333.0),
(5.0, 6.0, 7.0, 42.0, 4711.0, 23.0)]
Falls ``ENDE`` wirklich als Schlüsselwort an der entsprechenden Stelle vorkommen muss, dann lässt sich das sehr einfach hinzufügen.
Ansonsten kann man natürlich auch einen kleinen Parser von Hand schreiben:
Code: Alles auswählen
def iter_words(lines):
for line in lines:
for word in iter(line.split()):
yield word
def parse(words):
seen_constant = False
result = list()
for word in words:
try:
result.append(float(word))
except ValueError:
if seen_constant:
yield tuple(result)
seen_constant = False
result = list()
elif word.upper() == 'CONSTANT':
seen_constant = True
if seen_constant:
yield tuple(result)
print list(parse(iter_words(source.split('\n'))))
Verfasst: Donnerstag 8. Juni 2006, 21:36
von Mati
danke für die Hilfe...
habe es jetzt soweit mit mehreren regex hinbekommen...
das mit pyparsing kannte ich noch gar nicht
jetzt habe ich ein weiteres Problem das aber einfacher ist:
ich habe folgende strings:
st = "\n WORT"
st2 = "\n$ WORT"
st3 = "\n $ WORT"
Matchen soll der regex nur auf st !!!
Also wenn zwischen \n und WORT KEIN! Buchstabe auftritt...
hoffentlich kann mir jemand helfen...danke
Verfasst: Montag 12. Juni 2006, 13:29
von Mati
Hallo
vielleicht ist dashier besser zu verstehen:
ich will auf einen string matchen in dem alle empty spaces erlaubt sind AUSSER \n Zeilenumbrüche
also:
st1 = "ich \n hier " <- kein match
st2 = "ich bin hier" <- match
Danke euch
Verfasst: Montag 12. Juni 2006, 22:41
von BlackJack
Dazu braucht man keinen regulären Ausdruck: