ricevo il seguente input che voglio dividere in quattro parti:Splitting out METARs/TAF
-
KPDX 021453Z 16004KT 10SM FEW007 SCT060 BKN200 11/09 A3002 RMK
AO2 SLP166 T01060094 55008
TAF AMD KPDX 021453Z 0215/0312 10005KT P6SM FEW006 SCT060 BKN150
FM021800 11005KT P6SM SCT050 OVC100
FM022200 11007KT P6SM -RA OVC050
FM030500 12005KT P6SM -RA OVC035
KSEA 021453Z 15003KT 10SM FEW035 BKN180 11/09 A3001 RMK AO2
SLP168 60000 T01110089 58010
TAF AMD KSEA 021501Z 0215/0318 14004KT P6SM SCT020 BKN150
FM021800 16005KT P6SM SCT025 OVC090
FM030100 19005KT P6SM OVC070
FM030200 15005KT P6SM -RA OVC045
FM030600 16007KT P6SM -RA BKN025 OVC045
E 'un METAR, poi un TAF, poi un METAR, poi un TAF.
regole di ingresso:
- I codici aeroportuali possono cambiare, ma dovrebbero essere sempre 3 o 4 lettere.
- METARS inizierà con il codice dell'aeroporto, o "SPECI" seguito dal codice dell'aeroporto (SPECI KPDX).
- I TAF inizieranno con il codice dell'aeroporto o "TAF AMD" seguito dal codice dell'aeroporto (TAF AMD KPDX).
- In qualsiasi rapporto, il codice dell'aeroporto sarà sempre seguito dal timbro datetime.
- In un TAF, il timbro datetime sarà sempre seguito dai tempi validi (0215/0318 per esempio).
- Ci possono essere solo 2 report, o molti più di 4.
- Qualsiasi rapporto potrebbe essere solo una singola riga.
Voglio afferrare ogni rapporto da solo, quindi sto usando la regex ^(\\w+.*?)(?:^\\b|\\Z)
nel codice seguente:
ArrayList<String> reports = new ArrayList<String>();
Pattern pattern = Pattern.compile("^(\\w+.*?)(?:^\\b|\\Z)", Pattern.DOTALL|Pattern.MULTILINE);
Matcher matcher = pattern.matcher(input);
while(matcher.find())
reports.add(new String(matcher.group(1).trim()));
E le grandi opere, ottengo 4 risultati:
1:
KPDX 021453Z 16004KT 10SM FEW007 SCT060 BKN200 11/09 A3002 RMK
AO2 SLP166 T01060094 55008
2:
TAF AMD KPDX 021453Z 0215/0312 10005KT P6SM FEW006 SCT060 BKN150
FM021800 11005KT P6SM SCT050 OVC100
FM022200 11007KT P6SM -RA OVC050
FM030500 12005KT P6SM -RA OVC035
3:
KSEA 021453Z 15003KT 10SM FEW035 BKN180 11/09 A3001 RMK AO2
SLP168 60000 T01110089 58010
4:
TAF AMD KSEA 021501Z 0215/0318 14004KT P6SM SCT020 BKN150
FM021800 16005KT P6SM SCT025 OVC090
FM030100 19005KT P6SM OVC070
FM030200 15005KT P6SM -RA OVC045
FM030600 16007KT P6SM -RA BKN025 OVC045
ho incontrato un caso in cui il mio regex fallisce.Di tanto in tanto, una linea TAF verrà eseguito troppo a lungo e verrà avvolto (non ho alcun controllo su questo), quindi potrebbe sembrare (notare la "BKN150" diritto di seguito "TAF AMD PDX"):
-
KPDX 021453Z 16004KT 10SM FEW007 SCT060 BKN200 11/09 A3002 RMK
AO2 SLP166 T01060094 55008
TAF AMD KPDX 021453Z 0215/0312 10005KT P6SM FEW006 SCT060
BKN150
FM021800 11005KT P6SM SCT050 OVC100
FM022200 11007KT P6SM -RA OVC050
FM030500 12005KT P6SM -RA OVC035
KSEA 021453Z 15003KT 10SM FEW035 BKN180 11/09 A3001 RMK AO2
SLP168 60000 T01110089 58010
TAF AMD KSEA 021501Z 0215/0318 14004KT P6SM SCT020 BKN150
FM021800 16005KT P6SM SCT025 OVC090
FM030100 19005KT P6SM OVC070
FM030200 15005KT P6SM -RA OVC045
FM030600 16007KT P6SM -RA BKN025 OVC045
Quando questo accade, ottengo 5 risultati:
1:
KPDX 021453Z 16004KT 10SM FEW007 SCT060 BKN200 11/09 A3002 RMK
AO2 SLP166 T01060094 55008
2:
TAF AMD KPDX 021453Z 0215/0312 10005KT P6SM FEW006 SCT060
3:
BKN150
FM021800 11005KT P6SM SCT050 OVC100
FM022200 11007KT P6SM -RA OVC050
FM030500 12005KT P6SM -RA OVC035
4:
KSEA 021453Z 15003KT 10SM FEW035 BKN180 11/09 A3001 RMK AO2
SLP168 60000 T01110089 58010
5:
TAF AMD KSEA 021501Z 0215/0318 14004KT P6SM SCT020 BKN150
FM021800 16005KT P6SM SCT025 OVC090
FM030100 19005KT P6SM OVC070
FM030200 15005KT P6SM -RA OVC045
FM030600 16007KT P6SM -RA BKN025 OVC045
Chiunque può capire una regex che correttamente dividere questo caso strano? In alternativa, potrei provare a rimuovere l'interruzione di riga del problema nella stringa di input prima di eseguire la regex su di esso, ma non riesco a capire come rilevarla.
Questo funziona, tranne che c'è un altro caso possibile che ho dimenticato di menzionare. Ognuno dei report potrebbe essere una sola riga e la soluzione non funzionerà in quell'istanza. Modificherò la mia domanda per includere questa possibilità. – Ralgha
Quindi come si possono distinguere i report a riga singola da quelli racchiusi (sintatticamente)? –
Le regole di formattazione sono coerenti, un METAR inizia sempre con il codice di aeroporto o il codice aeroportuale "SPECI", seguito dal timbro di data/ora.Allo stesso modo i TAF iniziano sempre con il codice aeroportuale o il codice aeroportuale "TAF AMD", seguito dal timbro data/ora. Il timestamp nel TAF sarà sempre seguito dai tempi validi (0215/0318 per esempio). – Ralgha