にゃみかんてっくろぐ

猫か百合を見守る壁になりたい

気象庁の天気予報文をパースする ☀☁☂

天気予報文

気象庁の天気予報には 予報文 があります。

北東の風 日中 東の風 くもり 昼過ぎ まで 時々 晴れ 所により 夜遅く 雨

気象庁 | 天気予報 : 東京都 (10/20 11:00発表 21日の天気予報文)

やや難解ですが、 気象庁|予報用語 と照らし合わせることで下記であることが分かります。

時間 天気
0〜15時 くもり 時々 晴れ
15〜21時 くもり
21〜24時 くもり 所により 雨

天気予報文と正規表現

ここからは根拠のない独自研究です。

文法

気象庁が発表する天気予報文には 文法 が存在し、どの予報文もいずれかの文法にマッチします。以下は例です。

文法
天候 晴れ
天候 頻度 天候 晴れ 時々 くもり
天候 時間帯 天候 くもり 昼過ぎ から 夕方
天候 時間帯 頻度 天候 くもり 昼前 まで 時々 晴れ
天候 頻度 天候 時間帯 天候 晴れ 時々 くもり 夜のはじめ頃 から
天候 所により 天候 くもり 所により
天候 所により 時間帯 天候 くもり 所により 明け方 まで
天候 所により 修飾 所により 雷を伴い 激しく 降る
天候 所により 時間帯 修飾 所により 夕方 から 雷 を伴う
天候 頻度 天候 時間帯 天候 所により 時間帯 修飾 晴れ 時々 くもり 夕方 から 所により 夜遅く 雷を伴い 激しく 降る

正規表現

文法を正規表現で表すと、次のようになります(雪 後 雪などのありえない表現もマッチしますが、今回は無視します)。

(晴れ|くもり|雨|雪|雨か雪|雪か雨|雪 で ふぶく|雨 で 雷 を伴う|雨 で 雷を伴い 激しく 降る)( (時々|一時|後) (晴れ|くもり|雨|雪|雨か雪|雪か雨|雪 で ふぶく|雨 で 雷 を伴う|雨 で 雷を伴い 激しく 降る))?( ((朝晩|朝夕|夜)|(未明|明け方|朝|昼前|昼過ぎ|夕方|夜のはじめ頃|夜遅く)( (まで|から( 未明| 明け方| 朝| 昼前| 昼過ぎ| 夕方| 夜のはじめ頃| 夜遅く)?))?)( (時々|一時))? (晴れ|くもり|雨|雪|雨か雪|雪か雨|雪 で ふぶく|雨 で 雷 を伴う|雨 で 雷を伴い 激しく 降る))?( (所により|[^ ]+ では)( ((朝晩|朝夕|夜)|(未明|明け方|朝|昼前|昼過ぎ|夕方|夜のはじめ頃|夜遅く)( (まで|から( 未明| 明け方| 朝| 昼前| 昼過ぎ| 夕方| 夜のはじめ頃| 夜遅く)?))?))? ((晴れ|くもり|雨|雪|雨か雪|雪か雨|雪 で ふぶく|雨 で 雷 を伴う|雨 で 雷を伴い 激しく 降る)|(雷 を伴う|激しく 降る|雷を伴い 激しく 降る|霧)))?

何を言っているんだという感じなので、擬似的に表現をすると次のようになります。

天候( 頻度 天候)?( 時間帯( 頻度)? 天候)?( (所により|地名)( 時間帯)? (天候|修飾))?
項目 正規表現
天候 (晴れ|くもり|雨|雪|雨か雪|雪か雨|雪 で ふぶく|雨 で 雷 を伴う|雨 で 雷を伴い 激しく 降る)
頻度 (時々|一時|後) ※時間帯の後ろは (時々|一時)
時間帯 ((朝晩|朝夕|夜)|(未明|明け方|朝|昼前|昼過ぎ|夕方|夜のはじめ頃|夜遅く)( (まで|から( 未明| 明け方| 朝| 昼前| 昼過ぎ| 夕方| 夜のはじめ頃| 夜遅く)?))?)
地名 気象庁 | 気象警報・注意報や天気予報の発表区域 の「市町村等をまとめた地域」に準じる
修飾 (雷 を伴う|激しく 降る|雷を伴い 激しく 降る|霧)

※「雪 で ふぶく」等は修飾が入っていますが、簡単のために天候にまとめています。
※カバー出来ていない天気予報文が存在する可能性があります。

テスト

下記サイトで試してみるとマッチします。

f:id:no_clock:20191021004546p:plain

天気予報文とパーサ

正規表現のままパーサを書くのはつらいため、より簡単にして概ね次のルールでパーサを書きますました。

  • 入力は予報文、出力は0〜21時の3時間ごとの予報
  • 「時間帯」「所により(地名)」「何もない(終端)」が出現した場合に分割
  • 「所により」「頻度」が含まれる場合は予報を追記。それ以外は指定時間帯の予報として上書き

動作

$ ruby runner.rb

天気予報を入力: 晴れ 時々 くもり 夕方 から 雨 所により 夜遅く 雷を伴い 激しく 降る
解析結果:
{:wind=>nil,
 :weather=>
  {0=>"晴れ時々くもり",
   3=>"晴れ時々くもり",
   6=>"晴れ時々くもり",
   9=>"晴れ時々くもり",
   12=>"晴れ時々くもり",
   15=>"雨",
   18=>"雨",
   21=>"雨所により雷を伴い激しく降る"}}

天気予報を入力: 北東の風 日中 東の風 くもり 昼過ぎ まで 時々 晴れ 所により 夜遅く 雨
解析結果:
{:wind=>"北東の風 日中 東の風",
 :weather=>
  {0=>"くもり時々晴れ",
   3=>"くもり時々晴れ",
   6=>"くもり時々晴れ",
   9=>"くもり時々晴れ",
   12=>"くもり時々晴れ",
   15=>"くもり",
   18=>"くもり",
   21=>"くもり所により雨"}}

3時間ごとの天気予報がわかるようになりました。めでたしめでたし。