【旅程表 #04】(例外処理が)もう終わりだみぃ

前回最後に言った通りに正規表現についてやっていきます

そもそも正規表現とは

まずはそこから。平たく言えば欲しい文字列があるか探すための便利なツールみたいなものです(素人並説明)

たとえば'abcdefghijklmn'という文字列があって、この中に'de'という文字列があるかを探したい時、これだけなら前から見ていけばいいだけで済みますが、'eから始まってiで終わる5文字の文字列'があるかどうかやもっと複雑なものを見たいときにこの正規表現が役立ちます。 今回は、ジョルダン 乗換案内・路線情報・時刻表・運行情報サービスから出力したtxt形式の乗り換えデータをcsvファイルに落とし込んでいきます。

どうデータを抽出するか

ジョルダンは乗り換えを検索してテキストというボタンを押せば文章として乗り換え案内を出力することができます(←神サイト)(普段はYahoo!を使っているけれどurlでしか出力してくれないので解雇)

■東京    6番線発 
|  京浜東北線(大船行)   6.8km   4・6・7・8号車
|  04:41-04:53[12分]
|  6,930円
◇品川    5番線着・11番線発 [17分待ち]
|  東海道本線(東日本)(小田原行)   77.1km   
|  05:10-06:21[71分]
|   ↓ 

データを取ろうと思えばapiという手段もあるのですがいまいち使い勝手が悪い(後述)のと有料だったりするので使いません。

さて、この出力されたテキストデータからどのデータを抽出するかですが、 - 発着駅 - 発着時間 - 発着番線 - 行先 は簡単に取れそうです。列車番号とかはデータないのでそれは後から編集で。 まず、発着駅については■や◇というのが行の最初にあるのが目印になっているので、row[0]で判定して最初の空白文字までを取れば終わりです。 次に発着時間についても、HH:MM-HH:MM形式を探して抜くだけですし、発着番線については\d番線発(or着)って書かれてるのでそれで終わりです。発着番線についてはデータなしのため空欄になっている可能性もあるのでそもそもあるかどうかも確認しないといけません。余裕だろって思ったんですがどうもうまくいきません。

東海道本線(東日本)(熱海行)   






一行の中に半角と全角を混ぜるな






とまぁ問題はありましたがここまでをまとめると

datalist = ['1']
datalist.append(trigger.group()[1:])                                                #発駅
datalist.append(DATE_current + ' ' + txt_data[i+2][3:8])                            #発時間
datalist.append(re.match(jorudan_datapattern_train,txt_data[i+4]).group()[1:])      #着駅
datalist.append(DATE_current + ' ' + txt_data[i+2][9:14])                           #着時間
datalist.append(re.match(後述)             #路線
datalist.append('')                                                                 #列車番号
datalist.append('')                                                                 #列車種別
datalist.append(re.search('\(\D+行\)',txt_data[i+1]).group()[1:-1])                 #行先
if(re.search('\d+番線発',txt_data[i])):                                              #発番線
    datalist.append(re.search("\d+番線発",txt_data[i]).group()[:-3])
else:
    datalist.append('')
if(re.search('\d+番線着',txt_data[i+4])):                                            #着番線
    datalist.append(re.search('\d+番線着', txt_data[i+4]).group()[:-3])
else:
    datalist.append('')
    
txt_formatting.append(datalist)

最終的に

csv.writer(csv_file).writerows(txt_formatting)

csvに保存するので二次元配列的にデータを保存すればいいみたいです。

路線データ

これは始める前から絶対にめんどくさくなるというのがわかっていた問題ですが、路線名称についてはややこしいです。 まず東京→名古屋の乗り換えがこちら

■東京    14番線発 
|  のぞみ1号(N700系)(博多行)   366.0km   
|  06:00-07:34[94分]
|  6,380円( 指定席 4,720円 )
■名古屋    17番線着 

はい。特急や快速列車の場合は路線名ではなく列車名が表示されるんですね。なので路線名は得られません。もっというと東海道本線JR西日本区間琵琶湖線/京都線/神戸線と表示されるのでもやもや感はありますね。 これの対処法として発駅と着駅を両方含む路線をデータベースから引っ張ってくるということも考えましたが、マリンライナー(宇野線本四備讃線予讃線経由)と言ったものの処理が難しいのと、横浜→大船のように複数経路(東海道本線根岸線)が考えられる場合も考えないといけません。

鉄道以外

とりあえず鉄道のみの乗り換えに関しては一応動くという形になりましたが。実際のところは徒歩や航空機、船舶利用時にはフォーマットが異なってくるので動きませんorz。うーんでも例外処理とかいちいちやってたら完成しないのでとりあえず後から考えるということでーーー