2012-04-09 15 views
2

Also schreibe ich ein Python-Paket, das Daten von einem Echtzeit-NOAAPORT-Feed analysiert und in eine SQL-Datenbank wirft. Es fällt mir schwer, RegEx um den Kopf zu wickeln.NOAAPORT-Feed mit RegEx analysieren

ich besonders freu die LAT ... LON Linie entsprechen:

LAT...LON 3153 10127 3153 10118 3152 10118 3142 10122 
     3141 10127 3152 10127 

und das Beste, was ich mit oben kommen kann, ist:

r'^LAT...LON(.*)' 

Aber alle zwei Zahlen nach LAT. ..LON sind Breiten- und Längengrade, und ich kann nicht scheinen, dass es mit der nächsten Punktreihe übereinstimmt.

Auch das ist optional, ich würde auch gerne bestimmte Abschnitte dieser Tornado-Warnung gruppieren. Ich möchte den WMO-Header "TORSJT" trennen (Die ersten drei Buchstaben sind der Advisory-Typ, und die letzten drei sind das Wetterbüro, das den Advisory ausgab.

. TOR = Tornado Warnung SJT = San Angelo, TX Wetterbüro) und dann will ich nur die Warntext getrennt:

BULLETIN - EAS ACTIVATION REQUESTED 
TORNADO WARNING 
NATIONAL WEATHER SERVICE SAN ANGELO TX 
802 PM CDT SAT APR 7 2012 

THE NATIONAL WEATHER SERVICE IN SAN ANGELO HAS ISSUED A 

* TORNADO WARNING FOR... 
    NORTHWESTERN IRION COUNTY IN WEST CENTRAL TEXAS... 

* UNTIL 815 PM CDT 

* AT 757 PM CDT...A SEVERE THUNDERSTORM CAPABLE OF PRODUCING A 
    TORNADO WAS OVER EXTREME NORTHWESTERN IRION COUNTY...OR 24 MILES 
    NORTHEAST OF BIG LAKE...MOVING SOUTH SOUTHWEST AT 15 MPH. THIS 
    STORM HAS A HISTORY OF PRODUCING A TORNADO AND MAY PRODUCE A 
    TORNADO AT ANY TIME. 

    IN ADDITION TO DANGEROUS TORNADIC WINDS...OTHER HAZARDS INCLUDE... 
    LARGE DAMAGING HAIL UP TO TENNIS BALL SIZE. 
    DAMAGING STRAIGHT LINE WINDS IN EXCESS OF 60 MPH. 
    POTENTIALLY DEADLY LIGHTNING. 

*THE TORNADO WILL REMAIN OVER MAINLY RURAL AREAS OF... 
    NORTHWESTERN IRION COUNTY. 

PRECAUTIONARY/PREPAREDNESS ACTIONS... 

A SEVERE THUNDERSTORM WATCH REMAINS IN EFFECT UNTIL 1000 PM CDT 
SATURDAY EVENING FOR WEST CENTRAL TEXAS. 

&& 

ich im Grunde alles, was in einem Wörterbuch abgelegt werden soll, mit allen 3 seinen eigenen Schlüssel bekommen.

Hier ist die ganze intakte Referenz Warnung:

368 
WFUS54 KSJT 080102 
TORSJT 
TXC235-080115- 
/O.NEW.KSJT.TO.W.0012.120408T0102Z-120408T0115Z/ 

BULLETIN - EAS ACTIVATION REQUESTED 
TORNADO WARNING 
NATIONAL WEATHER SERVICE SAN ANGELO TX 
802 PM CDT SAT APR 7 2012 

THE NATIONAL WEATHER SERVICE IN SAN ANGELO HAS ISSUED A 

* TORNADO WARNING FOR... 
    NORTHWESTERN IRION COUNTY IN WEST CENTRAL TEXAS... 

* UNTIL 815 PM CDT 

* AT 757 PM CDT...A SEVERE THUNDERSTORM CAPABLE OF PRODUCING A 
    TORNADO WAS OVER EXTREME NORTHWESTERN IRION COUNTY...OR 24 MILES 
    NORTHEAST OF BIG LAKE...MOVING SOUTH SOUTHWEST AT 15 MPH. THIS 
    STORM HAS A HISTORY OF PRODUCING A TORNADO AND MAY PRODUCE A 
    TORNADO AT ANY TIME. 

    IN ADDITION TO DANGEROUS TORNADIC WINDS...OTHER HAZARDS INCLUDE... 
    LARGE DAMAGING HAIL UP TO TENNIS BALL SIZE. 
    DAMAGING STRAIGHT LINE WINDS IN EXCESS OF 60 MPH. 
    POTENTIALLY DEADLY LIGHTNING. 

*THE TORNADO WILL REMAIN OVER MAINLY RURAL AREAS OF... 
    NORTHWESTERN IRION COUNTY. 

PRECAUTIONARY/PREPAREDNESS ACTIONS... 

A SEVERE THUNDERSTORM WATCH REMAINS IN EFFECT UNTIL 1000 PM CDT 
SATURDAY EVENING FOR WEST CENTRAL TEXAS. 

&& 

LAT...LON 3153 10127 3153 10118 3152 10118 3142 10122 
     3141 10127 3152 10127 
TIME...MOT...LOC 0102Z 355DEG 11KT 3148 10125 

$$ 
+1

Würde gerne einen NOAAPORT-Feed bekommen. Woher bekommst du es, wenn es dir nichts ausmacht, dass ich frage? – ONDEV

Antwort

2

Sie sind im Grunde mehrzeiligen Regex Matching durchzuführen versuchen.

Statt greedy Matching verwenden, .*, versuchen Sie so etwas wie dies mit:

import re 

regex = re.compile('LAT...LON([0-9\s]+)', flags=re.MULTILINE) 
matches = regex.search('''LAT...LON 3153 10127 3153 10118 3152 10118 3142 10122 
     3141 10127 3152 10127 
TIME...MOT...LOC 0102Z 355DEG 11KT 3148 10125''') 
print re.split('\s+', matches.group(1))[1:-1] 

In einer Live-Konsolensitzung:

>>> import re 
>>> 
>>> regex = re.compile('LAT...LON([0-9\s]+)', flags=re.MULTILINE) 
>>> matches = regex.search('''LAT...LON 3153 10127 3153 10118 3152 10118 3142 10122 
...  3141 10127 3152 10127 
... TIME...MOT...LOC 0102Z 355DEG 11KT 3148 10125''') 
>>> print re.split('\s+', matches.group(1))[1:-1] 
['3153', '10127', '3153', '10118', '3152', '10118', '3142', '10122', '3141', '10127', '3152', '10127'] 
>>> 
1

. passt alles andere als eine neue Zeile, wenn die DOTALL Flag angegeben.
So fügen Sie einfach in einem \n und dann einem anderen .*:

import re 

test = '''LAT...LON 3153 10127 3153 10118 3152 10118 3142 10122 
     3141 10127 3152 10127 
TIME...MOT...LOC 0102Z 355DEG 11KT 3148 10125''' 

result = re.search(r'LAT...LON.*\n.*', test) 

print result.group() 

oder

result = re.search(r'LAT...LON[\d\s]+\n[\d\s]+', test) 
2

Andere den Regex Bau abgedeckt haben, aber Sie sollten auch vorsichtig sein, wie Sie re verwenden. Wenn Sie einen großen Block von Text re.findall greifen möchten, kann es einfacher sein, da es immer noch mehrzeilig ist und eine Liste von Zeichenfolgen (anstelle von Übereinstimmungsobjekten) zurückgibt. Offensichtlich hängt es davon ab, was Sie tun möchten. Im Gegensatz dazu findet re.match nur Übereinstimmungen am Anfang einer Zeile.

Verwandte Themen