#!/usr/local/bin/ruby19 -- # -*- encoding: utf-8 -*- ############################### # Author: vagus # LastUpdate: 2010-5-31 # 無保証、無制限(改変、再配布 etc) ############################### # Modified by G-HAL(fenix.ne.jp) # Tue,15 Jun,2010 - Fri,18 Jun,2010 # Tue,31 Aug,2010 # Sun,13 Feb,2011 ############################### # # KEN_ALL.CSV から Anthy 用の zipcode.t を作成する # (事前に ken_all.lzh を落として伸張しておくこと) # % wget http://www.post.japanpost.jp/zipcode/dl/kogaki/lzh/ken_all.lzh # % lha xg ken_all.lzh # ############################### # 既知の問題: # ・文字列でソートするから数字部分の並びがおかしい # # (JIGYOSYO.CSV は一部、第3水準の漢字を使っていて、EUC-JP に変換できないので # 入れない。) # ############################### if 1 <= ARGV.size IN_FILE = ARGV[0] else IN_FILE = "./KEN_ALL.CSV" end if 2 <= ARGV.size OUT_FILE = ARGV[1] else OUT_FILE = "./zipcode_ken_base.txt" end #******************************************** # 「種市第46地割〜第49地割」みたいなのを # ["種市第46地割", "種市第47地割", "種市第48地割", "種市第49地割"] # に展開する関数 #******************************************** def expand_range(str) str = str.tr("[0-9]","[0-9]") str.match(/^([^0-9]*)([0-9]+)[^0-9]+([0-9]+)([^0-9]*)$/) ($2.to_i..$3.to_i).map{|x| "#{$1}#{x.to_s.tr("[0-9]","[0-9]")}#{$4}" } end #-------------------------------------------- # KEN_ALL.CSV を読んで必要な field を抜き出す #-------------------------------------------- ken_all_src = [] open(IN_FILE, "r:CP932"){|f| # U+FF0D, U+2014, U+2015, U+2500 は「−」(U+2212)に置換 # U+FF5E, U+301C は「〜」(U+301C)に置換 ken_all_src = f.read.encode("UTF-8")\ .gsub('"','')\ .gsub('-','−')\ .gsub('—','−')\ .gsub('―','−')\ .gsub('─','−')\ .gsub('~','〜')\ .each_line.map{|line| e =line.chomp.split(",") ["#{e[2]}", "#{e[6]}", "#{e[7]}", "#{e[8]}"] } } #----------------------------------------- # 複数行にまたがっている奴を一行にまとめる #----------------------------------------- ken_all = [] zipcode = "-1" #ken_all_src[0][0] item3_adr = "-1" #ken_all_src[0][3] hold = "-1" #ken_all_src[0..2] ken_all_src.each{|item| # 括弧が複数行に渡る場合は連結する。 if item[3] =~ /([^)]+$/ zipcode = item[0] item3_adr = item[3] hold = item[0..2] elsif item[0] == zipcode && item[3] !~ /[()]/ item3_adr += item[3] else if item[0] == zipcode && item[3] =~ /)/ item3_adr += item[3] item[3] = item3_adr end zipcode = -1 # 複数行にまたがっていない場合/複数行の連結済み。 item3_head = "" item3_lst = [""] item3_tail = "" # 複数丸括弧は一つにしておく # 「ミッドランドスクエア」のみ。 item[3] = item[3].sub(")(","") if item[3] =~ /[いる]場合|一円$/ # 住所として無意味なものを削除 # (「以下に掲載がない場合」「の次に番地がくる場合」 # 「新庄村一円」) item[3] = "" item3_lst = [item[3]] elsif item[3] =~ /[「」]/ # ややこしいのでそのまま放置。 item3_lst = [item[3]] elsif item[3] =~ /^([^(]*)((.*))([^)]*$)/ item[3].match(/^([^(]*)((.*))([^)]*$)/) item3_head = $1 item3_contents = $2 item3_tail = $3 # item[3](町域)が複数に分かれる場合の対応 if item3_contents =~ /、/ # 「穴明22地割、穴明23地割」のような場合は分割する item3_lst = item3_contents.split("、") elsif item3_contents =~ /[~〜]/ # 「越中畑64地割〜越中畑66地割」のような場合は展開する item3_lst = expand_range(item3_contents) if item3_lst[0] =~ /^0$/ # 展開失敗。 item3_lst = [item3_contents] end else if item3_contents !~ /(丁目|番地)/ item3_lst = [item3_contents] end end else item3_lst = [item[3]] end # ken_all にまとめる item3_lst.each{|y| ken_all << [item[0], item[1..2].join + item3_head + y + item3_tail] } end } # 「江田島町国有無番地」はどうするか #----------------------------- # 英数記号を半角にした候補を追加 #----------------------------- hankaku = [] ken_all.each{|item| if item[1] =~ /[−0-9A-Za-z()]/ hankaku << [item[0], item[1].tr("−0-9A-Za-z()", "-0-9A-Za-z()")] end } ken_all += hankaku #----------------------------- # sort, uniq して成形して出力 #----------------------------- open(OUT_FILE, "w"){|f| ken_all.uniq.sort{|x, y| [x[0], x[1]] <=> [y[0], y[1]] }.each{|x| f.puts "#{x[0]} #CNS #{x[1].encode('EUC-JP')}" } } # [ End of File ]