Skip to content

Instantly share code, notes, and snippets.

@zakuroishikuro
Last active October 24, 2023 06:12
Show Gist options
  • Save zakuroishikuro/826f1be2840509d470fa to your computer and use it in GitHub Desktop.
Save zakuroishikuro/826f1be2840509d470fa to your computer and use it in GitHub Desktop.
住所を分ける正規表現をチェックするやつ
require 'csv'
require 'optparse'
#
# なるべく短い正規表現で住所を「都道府県/市区町村/それ以降」に分けるエクストリームスポーツ
# http://qiita.com/zakuroishikuro/items/066421bce820e3c73ce9
#
# 正規表現で住所の「都道府県/市区町村/それ以降」をキャプチャできるか試すスクリプト
# 使い方はとりあえず実行すれば分かると思います
#
# このスクリプトと同じフォルダに以下のzipのKEN_ALL.csvを置いてお使いください
# http://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip
#
# 動作確認: ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]
#
@sample_address = "東京都文京区後楽1丁目3−61"
@sample_answer = ["東京都", "文京区", "後楽1丁目3−61"]
# 起動時に引数「-e」をつけたらエクストリームモードをON
OptionParser.new.on('-e', '--extreme'){ @extreme = true }.parse! ARGV
@extreme_address = "壱丁目二番地3号都道府県市区町村ハイツ456号室" #「それ以降」に追加される番地・マンション名
# 住所データを取得 (同じフォルダ内のKEN_ALL.csvを読み込む)
print "\nKEN_ALL.csvをパース中... "
address_list = []
csv_path = File.expand_path "../KEN_ALL.CSV", __FILE__
if !File.exists? csv_path
puts "\n\nERROR: KEN_ALL.CSVが存在しません。"
puts " 以下のzip内のKEN_ALL.CSVをこのスクリプトと同じフォルダに置いてください。"
puts " http://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip\n\n"
exit
end
CSV.foreach csv_path, encoding:"Shift_JIS:UTF-8" do |row|
#都道府県、市区町村、町域名のみ取り出す
#このcsvはデータ構造がうんこで、本当は町域名の結合とかする必要があるんだけど、今回はしなくても問題ない
if @extreme
address_list << [*row[6..7], "#{row[8]}#{@extreme_address}"]
else
address_list << row[6..8]
end
end
puts @extreme ? "完了 (extreme)" : "完了"
# 無限ループ
trap :INT, :exit #(control + Cで終了)
loop do
# 正規表現を取得
puts "\n正規表現を入力してください (control + cで終了):"
begin
rex = /#{gets.strip}/
rescue RegexpError
puts "\nERROR: 正規表現の作成に失敗しました。", " #{$!}"
next
end
if rex.source.empty?
puts "ERROR: 文字列が空です。"
next
end
# サンプル住所で試してみる。駄目だったら入力しなおし。
m = @sample_address.match(rex).captures rescue []
unless m == @sample_answer
puts "\nERROR: サンプル住所の分割に失敗しました。やり直してください。"
puts " 住所: #{@sample_address}"
puts " 正解: #{@sample_answer}"
puts " 回答: #{m}"
next
end
# 正規表現のマッチ結果を取得
result = address_list.map do |address|
address.join.match(rex).captures rescue []
end
# 判定
fail_count = 0
address_list.zip(result).each do |address, match|
if address != match
puts "失敗... #{address * ?|}\t(#{match * ?|})"
fail_count += 1
end
end
# 結果を出力
all = address_list.count
pct = fail_count.to_f / all * 100
puts "\n正規表現: ", rex.source
puts "\n失敗数: ", "#{fail_count} / #{all} (#{pct.to_i}%)"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment