tôi nhận được đầu vào sau đây mà tôi muốn chia thành bốn phần:tách ra METARs/TAFs
-
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
Đó là một METAR, sau đó một TAF, sau đó một METAR, sau đó một TAF.
quy tắc Input:
- Các mã sân bay có thể thay đổi, nhưng phải luôn luôn được 3 hoặc 4 chữ cái.
- METARS sẽ bắt đầu bằng mã sân bay hoặc "SPECI" theo sau là mã sân bay (SPECI KPDX).
- TAF sẽ bắt đầu bằng mã sân bay hoặc "TAF AMD" theo sau là mã sân bay (TAF AMD KPDX).
- Trong bất kỳ báo cáo nào, mã sân bay sẽ luôn được theo sau bởi dấu ngày giờ.
- Trong TAF, dấu ngày giờ sẽ luôn được theo sau bởi thời gian hợp lệ (ví dụ: 0215/0318).
- Chỉ có thể có tối thiểu 2 báo cáo hoặc nhiều hơn 4 báo cáo.
- Mọi báo cáo có thể chỉ là một dòng.
Tôi muốn lấy mỗi báo cáo của chính nó, vì vậy tôi đang sử dụng regex ^(\\w+.*?)(?:^\\b|\\Z)
trong đoạn mã sau:
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()));
Nó hoạt động tuyệt vời, tôi nhận được 4 kết quả:
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
Tôi đã gặp một trường hợp regex của tôi thất bại.Thỉnh thoảng, một dòng TAF sẽ chạy quá dài và sẽ được bao bọc (Tôi đã không kiểm soát này), vì vậy nó có thể trông giống như (chú ý "BKN150" ngay bên dưới "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
Khi điều này xảy ra, tôi nhận được 5 kết quả:
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
bất cứ ai có thể hình dung ra một regex đúng sẽ chia trường hợp kỳ lạ này? Ngoài ra tôi có thể cố gắng để loại bỏ sự cố ngắt dòng trong chuỗi đầu vào trước khi chạy regex trên nó, nhưng tôi không thể tìm ra cách để phát hiện nó.
Điều đó có hiệu quả, ngoại trừ một trường hợp có thể xảy ra khác mà tôi đã bỏ qua. Bất kỳ một trong các báo cáo chỉ có thể là một dòng duy nhất và giải pháp của bạn không thành công trong trường hợp đó. Tôi sẽ chỉnh sửa câu hỏi của tôi để bao gồm khả năng đó. – Ralgha
Sau đó, làm cách nào bạn có thể phân biệt các báo cáo một dòng từ các báo cáo xung quanh (cú pháp)? –
Quy tắc định dạng nhất quán, METAR sẽ luôn bắt đầu bằng mã sân bay hoặc mã sân bay "SPECI", theo sau là dấu ngày/giờ.Tương tự như vậy, TAF luôn bắt đầu bằng mã sân bay hoặc mã sân bay "TAF AMD", theo sau là dấu ngày/giờ. Dấu thời gian trong TAF sẽ luôn được theo sau bởi thời gian hợp lệ (ví dụ: 0215/0318). – Ralgha