4つの部分に分割したい次の入力を取得します。
-
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
それはMETAR、次にTAF、次にMETAR、次にTAFです。
入力ルール:
- 空港コードは変更される可能性がありますが、常に3文字または4文字である必要があります。
- METARSは、空港コード、または「SPECI」の後に空港コード(SPECI KPDX)のいずれかで始まります。
- TAFは、空港コード、または「TAF AMD」の後に空港コード(TAF AMD KPDX)のいずれかで始まります。
- どのレポートでも、空港コードの後には常に日時スタンプが続きます。
- TAFでは、日時スタンプの後に常に有効な時刻が続きます(たとえば、0215/0318)。
- レポートは2つだけ、または4つ以上になる可能性があります。
- レポートは1行だけにすることができます。
各レポートを単独で取得したいので^(\\w+.*?)(?:^\\b|\\Z)
、次のコードで正規表現を使用しています。
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() ) );
それはうまくいきます、私は4つの結果を得ます:
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
正規表現が失敗するケースに遭遇しました。時折、TAF回線が長すぎて折り返されることがあるため(これを制御することはできません)、次のようになります(「TAF AMDPDX」のすぐ下にある「BKN150」に注意してください)。
-
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
これが発生すると、5つの結果が得られます。
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
この奇妙なケースを正しく分割する正規表現を誰かが理解できますか?または、正規表現を実行する前に、入力文字列の問題のある改行を削除しようとすることもできますが、それを検出する方法がわかりません。