Excelの質問です。住所から“市区町村のみ”の情報を抽出することは出来ますでしょうか。

今、東京都の東京タワー、福島県のフォレストパークあだたら、岐阜県のハリヨ公園など、住所データが5万件ぐらいあります。

東京都港区芝公園4丁目2−8
福島県安達郡大玉村玉井字長久保68
岐阜県山県市大森


この中から、

港区
安達郡
山県市

など、都道府県名を除いた市区町村名(区名)のみ抽出したいのです。

東京都港区
福島県安達郡
岐阜県山県市

でも構いません。
というのもおそらく都道府県名は岐阜県の山県市のみ気を付ければ、「*県」を空白に置換して消去、東京都・大阪府・京都府を置換で消去すれば、事足りるからです。

しかし市区町村の抽出は、千葉県の市川市など、「市*」を「市」に置換すると、市区町村が消えて「市」だけになってしまいますし。
「郡」は郡上市とか郡山市とか、置換して消去というやり方では市区町村名の表示がおかしくなる可能性もあります。

気を付けて少し時間をかければ置換して抽出できるのですが…「もっと効率的な方法がある!」ようでしたら、ご教授いただけますとありがたいです。
よろしくお願い致します。

回答の条件
  • 1人10回まで
  • 登録:
  • 終了:2016/11/19 17:04:00
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:a-kuma3 No.2

回答回数4973ベストアンサー獲得回数2154

ポイント3000pt

以下のコードを標準モジュールに貼り付けて、extract_city サブルーチンを実行してください。
A列の住所から市区町村郡を切り出して、B列にセットします。

Sub extract_city()
    source_col = 1      ' A列 : 住所
    dest_col = 2        ' B列 : 市区町村

    last_row = Cells(Rows.Count, source_col).End(xlUp).Row

    Set re_z = CreateObject("VBScript.RegExp")
    Dim re_c(7)
    For i = 0 To 7
        Set re_c(i) = CreateObject("VBScript.RegExp")
    Next

    re_z.Pattern = "^(.{2}[都道府]|.{2,3}[県])(.+)"
    re_c(0).Pattern = "^(郡山市|市川市|市原市|郡上市|蒲郡市|四日市市|大和郡山市|廿日市市|小郡市|野々市市|高市郡|余市郡)"
    re_c(1).Pattern = "^([^郡]+郡)"
    re_c(2).Pattern = "^([^市]+市)"
    re_c(3).Pattern = "^([^区]+区)"
    re_c(4).Pattern = "^([^町]+町)"
    re_c(5).Pattern = "^([^村]+村)"
    re_c(6).Pattern = "^([^区]+区)"     ' 東京都用
    re_c(7).Pattern = "^([^市]+市)"     ' 東京都用

    For r = 2 To last_row
        s = Cells(r, source_col).Value
        Set mat = re_z.Execute(s)
        If mat.Count = 0 Then
            Cells(r, dest_col).Value = "都道府県が見つかりません"
            GoTo Continue
        End If
        Z = mat(0).SubMatches(0)
        s = mat(0).SubMatches(1)

        i_begin = 0
        i_end = 5
        If Z = "東京都" Then
            i_begin = 6
            i_end = 7
        End If

        For i = i_begin To i_end
            Set mat = re_c(i).Execute(s)
            If mat.Count > 0 Then
                If i <> 1 Then
                    Cells(r, dest_col).Value = mat(0).SubMatches(0)
                Else    ' 「郡」だけ特別扱い
                    Set mat2 = re_c(2).Execute(s)   ' 「市」を含む?
                    If mat2.Count > 0 Then
                        '短い方を採択
                        If Len(mat(0).SubMatches(0)) > Len(mat2(0).SubMatches(0)) Then
                            Cells(r, dest_col).Value = mat2(0).SubMatches(0)
                        Else
                            Cells(r, dest_col).Value = mat(0).SubMatches(0)
                        End If
                    Else
                        Cells(r, dest_col).Value = mat(0).SubMatches(0)
                    End If
                End If
                GoTo Continue
            End If
'           DoEvents
        Next
Continue:
    Next
End Sub

五万件だと数分かかると思います。
その間にもシートを操作したいのであれば、末尾の方でコメントにしてある DoEvents を活かしてください。
コメントを外すと、完了までの時間は更に長くなりますが、処理中にもシートの操作ができます。

処理内容の説明をしておきます。

「郡→市→区→町→村」の順番で検索すると、エラーの発生を最小にすることができます

上記のロジックを参考にしました。
ただ、「郡」や「市」を市の名前に含む9件を例外扱いにしただけでは、以下のような住所が適切に扱えません。

山形県南陽市郡山
大阪府交野市郡津
山口県山口市小郡
鹿児島県鹿児島市郡元町

そこらあたりを、実際の住所データ(何かの回答の折に使った 9000件くらいの全国の)を使いながらロジックを調整しました。
「郡」が見つかった場合には、「市」でも探してみて、短い方を採用しています。
それでも、「奈良県高市郡」、「北海道余市郡」は正しく抽出できないので、特別扱いにしています。

対象の住所によっては、正しく処理できないものがあると思います。
コメントで紹介されている総務省の「全国地方公共団体コード」から表引きにすることもちらっと考えましたが、

  • 「郡」の情報がない
  • 処理に時間がかかるかも

と思って止めました。


後、質問では「郡」を切り出しの対象にしているのでそのような処理にしていますが、「郡」で切ってしまうと、「町」や「村」が抽出されないと思います。
入力済みの住所データ次第ですが、「○○郡△△村」のような表記になっているはずなので。



追記です。
今、テレビを見てて「野々市市」というのがあるというのを知りました。
コードに反映してます。
総務省|電子自治体|全国地方公共団体コード」から、「市」の名称で「郡」と「市」が入るものが他にないことは確認しました。
#「郡」も例外的なのがもっとあるんだろうなあ...



追記です。

#「郡」も例外的なのがもっとあるんだろうなあ...

郡の変遷」に 2014年4月1日時点での「郡」の情報がまとめられていて、「郡」の名称に「市」が入るのは、「余市」と「高市」だけっぽいことは確認しました。



更に追記。
面白そうなので、「全国地方公共団体コード」から表引きについてもちょっと考えてみました。
「郡」の情報がないので、「○○郡」を外して「町」や「村」を抽出する前提です。

東京都の「区」と、他の「市」は良いのですが、「町」と「村」には、その前に「郡」がついているようです。
「全国地方公共団体コード」には「郡」の情報がありませんので、表引きをするには先頭一致ではなく中間一致で探すことになります。
中間一致で探す場合にネックになるのが、他の市町村を包含する名前があること。
例えば、「千葉県栄町」と「鳥取県北栄町」や「愛知県東栄町」です。
これをクリアするためには、表の方の名称が長い方から探さなくちゃいけません。
表引きの場合、ハッシュや二分探索を使うと速いんですが、それが使えず、名称の長い順に並べた表を使って線形探索(ありていに言えば、先頭から探す)。
1800近くある表なので、これは遅そうだ、と。

先頭一致で探せばそれなりに速くなると思いますが、その場合には「郡」を切り取らなくちゃいけない。
ちょっと邪魔くさいのが「郡上郡」。
2004年に「郡上市」になったらしいですが。

東京都の「区」と、「市」を先に振り分けて、「郡」を切り取れれば、残りは「町」と「村」。
名称に両方の文字を含むのは、「群馬県玉村町」と「宮城県村田町」のふたつ。
「町」で先に切り出せば良いかな、と思ったら「長崎県大町町」なんてのがある。

というわけで、市町村の一覧を利用する場合には、以下のような手順になりそう。

  1. 東京都で「区」を切り出す
  2. 都道府県を切り取って、先頭一致で表引きで「市」を切り出す
  3. 「郡上郡」を特別扱いにして、「郡」を切り取る
  4. 「大町町」を特別扱いにして、「町」を切り取る
  5. 「村」を切り取る

「町」、「村」の切り取りは、まとめて先頭一致の表引きでも良いでしょう(遅いけど)。

表引きでも、素直に表と照らし合わせるだけでは駄目でヒューリスティックなロジックにならざるを得なし、市区町村のリストは頻繁ではないにしても更新が入りますので使い続けるつもりのプログラムなら保守が必要。
だったら表なんか使わなくても良いかなあ、という印象です。



またまた追記。
表引きにするなら、「読み仮名データの促音・拗音を小書きで表記するもの - zip圧縮形式 日本郵便」を使う方が良さそう。
この一覧の 8列目を抽出して重複を取り除けば

  • 市+区
  • 郡+町
  • 郡+村

の完全なリストが手に入る。
全部で 1894件。
これを長い順に並べ替えて、住所から都道府県を切り取った文字列と先頭一致で比較して一致したら採用。
「郡は要らない」とか「郡の方を採用」は、一覧にある文字列を加工する感じでしょうか。
ロジックは単純になりますね。

# 総務省の「全国地方公共団体コード」の方は 1741 件で、150件ほど差があるのは廃止になったものを一部含んでいるからかな?



追記。

# 総務省の「全国地方公共団体コード」の方は 1741 件で、150件ほど差があるのは廃止になったものを一部含んでいるからかな?

いや、郵便番号の方は「○○市○○区」の表記だからだった。
一部の差異を除いて、ほぼ同じ。
漢字の表記の違いが2件と、「郡」ではなく「島」という表記が 2件(三宅島と八丈島)。
東京都だからだなあ、きっと。



またまた追記です。
郵便番号の一覧をベースに表引きを軽くやってみました。

性能的な問題は、表を作るときに最大の文字数を控えておき、住所から切り出すときには頭から切り取る文字数を、最大文字数からひとつずつ減らして、その度に表(Dictionary オブジェクト)にあるかどうかを確認するというふうに対処しました。
回答に書いた正規表現を使う場合と、実行時間はさほど変わらない感じです。

ただ、ちょっと問題がありまして。
手持ちの 9000件くらいのデータで試してみたんですが、250件くらいが引き当てできていません。
幾つかサンプリングして調べてみると、以下のようなパターンが。

  • 「町」が「市」になった
  • いくつかの「町」、「村」が合併して市になった
  • 政令指定都市になり、「区」が入った

良くも悪くも入手できる一覧は最新なので、市区町村を切り出す対象の住所に古いものが含まれると、取りこぼしがありそうです。
ぼくが試したデータでは 2.8% を取りこぼしているので、プログラムで切り出した方が例外が少ないという結果になります。
一覧表のデータは、プログラムで切り出した値の検算に使うのが良いかな、という気がしました。

他3件のコメントを見る
id:a-kuma3

2つだけ、

東京都西多摩郡瑞穂町大字高根×××
東京都西多摩郡瑞穂町大字箱根ケ崎×××
(※)×は数字

が空白セルでしたが、

手元のプログラムでは直してたんですが、回答に反映するのを忘れてました (^^;
もし、次に使うことがあるようでしたら、以下の「★」をつけたところを追加・修正してください。

    Set re_z = CreateObject("VBScript.RegExp")
    Dim re_c(10)            ' ★
    For i = 0 To 10         ' ★
        Set re_c(i) = CreateObject("VBScript.RegExp")
    Next

    ...

    re_c(5).Pattern = "^([^村]+村)"
    re_c(6).Pattern = "^([^区]+区)"     ' 東京都用
    re_c(7).Pattern = "^([^市]+市)"     ' 東京都用
    re_c(8).Pattern = "^([^郡]+郡)"     ' 東京都用  ' ★
    re_c(9).Pattern = "^([^町]+町)"     ' 東京都用  ' ★
    re_c(10).Pattern = "^([^村]+村)"    ' 東京都用  ' ★
    
    ...
        If Z = "東京都" Then
            i_begin = 6
            i_end = 10          ' ★
        End If

# 最近、プログラムでやり取りすることが滅多にないので、とても楽しかった :-)

2016/11/19 18:04:51
id:moon-fondu

ありがとうございます。楽しんでいただいて光栄です。またよろしくお願いしますm(__)m

2016/11/20 11:48:18

その他の回答2件)

id:jccrh1 No.1

回答回数111ベストアンサー獲得回数19

ポイント10pt

moon-fondu様
こんにちは。

私はプログラマなので、市区町村データとマッチして取得しています。

例)総務省のサイトでEXCELで用意されています。
http://www.soumu.go.jp/denshijiti/code.html

例)Yahooではプログラムが作れる人ならWEB APIで用意されています。
http://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/addressdirectory.html

【注意事項】
・「ケ」と「ヶ」の違いもあるかも知れません。
・漢字の違いに注意が必要かも知れません。
 龍ケ崎市、竜ヶ崎市 等々
・市区町村をどこまで取得するかも検討が必要です。
 札幌市 までか?
 札幌市中央区 までか?
・市区町村合併により町名変更も注意する必要があります。

以上、ご検討ください。

id:moon-fondu

APIは難しいですね!うーん、具体的な方法をお教えいただければありがたいのですが…。

2016/11/19 16:21:50
id:a-kuma3 No.2

回答回数4973ベストアンサー獲得回数2154ここでベストアンサー

ポイント3000pt

以下のコードを標準モジュールに貼り付けて、extract_city サブルーチンを実行してください。
A列の住所から市区町村郡を切り出して、B列にセットします。

Sub extract_city()
    source_col = 1      ' A列 : 住所
    dest_col = 2        ' B列 : 市区町村

    last_row = Cells(Rows.Count, source_col).End(xlUp).Row

    Set re_z = CreateObject("VBScript.RegExp")
    Dim re_c(7)
    For i = 0 To 7
        Set re_c(i) = CreateObject("VBScript.RegExp")
    Next

    re_z.Pattern = "^(.{2}[都道府]|.{2,3}[県])(.+)"
    re_c(0).Pattern = "^(郡山市|市川市|市原市|郡上市|蒲郡市|四日市市|大和郡山市|廿日市市|小郡市|野々市市|高市郡|余市郡)"
    re_c(1).Pattern = "^([^郡]+郡)"
    re_c(2).Pattern = "^([^市]+市)"
    re_c(3).Pattern = "^([^区]+区)"
    re_c(4).Pattern = "^([^町]+町)"
    re_c(5).Pattern = "^([^村]+村)"
    re_c(6).Pattern = "^([^区]+区)"     ' 東京都用
    re_c(7).Pattern = "^([^市]+市)"     ' 東京都用

    For r = 2 To last_row
        s = Cells(r, source_col).Value
        Set mat = re_z.Execute(s)
        If mat.Count = 0 Then
            Cells(r, dest_col).Value = "都道府県が見つかりません"
            GoTo Continue
        End If
        Z = mat(0).SubMatches(0)
        s = mat(0).SubMatches(1)

        i_begin = 0
        i_end = 5
        If Z = "東京都" Then
            i_begin = 6
            i_end = 7
        End If

        For i = i_begin To i_end
            Set mat = re_c(i).Execute(s)
            If mat.Count > 0 Then
                If i <> 1 Then
                    Cells(r, dest_col).Value = mat(0).SubMatches(0)
                Else    ' 「郡」だけ特別扱い
                    Set mat2 = re_c(2).Execute(s)   ' 「市」を含む?
                    If mat2.Count > 0 Then
                        '短い方を採択
                        If Len(mat(0).SubMatches(0)) > Len(mat2(0).SubMatches(0)) Then
                            Cells(r, dest_col).Value = mat2(0).SubMatches(0)
                        Else
                            Cells(r, dest_col).Value = mat(0).SubMatches(0)
                        End If
                    Else
                        Cells(r, dest_col).Value = mat(0).SubMatches(0)
                    End If
                End If
                GoTo Continue
            End If
'           DoEvents
        Next
Continue:
    Next
End Sub

五万件だと数分かかると思います。
その間にもシートを操作したいのであれば、末尾の方でコメントにしてある DoEvents を活かしてください。
コメントを外すと、完了までの時間は更に長くなりますが、処理中にもシートの操作ができます。

処理内容の説明をしておきます。

「郡→市→区→町→村」の順番で検索すると、エラーの発生を最小にすることができます

上記のロジックを参考にしました。
ただ、「郡」や「市」を市の名前に含む9件を例外扱いにしただけでは、以下のような住所が適切に扱えません。

山形県南陽市郡山
大阪府交野市郡津
山口県山口市小郡
鹿児島県鹿児島市郡元町

そこらあたりを、実際の住所データ(何かの回答の折に使った 9000件くらいの全国の)を使いながらロジックを調整しました。
「郡」が見つかった場合には、「市」でも探してみて、短い方を採用しています。
それでも、「奈良県高市郡」、「北海道余市郡」は正しく抽出できないので、特別扱いにしています。

対象の住所によっては、正しく処理できないものがあると思います。
コメントで紹介されている総務省の「全国地方公共団体コード」から表引きにすることもちらっと考えましたが、

  • 「郡」の情報がない
  • 処理に時間がかかるかも

と思って止めました。


後、質問では「郡」を切り出しの対象にしているのでそのような処理にしていますが、「郡」で切ってしまうと、「町」や「村」が抽出されないと思います。
入力済みの住所データ次第ですが、「○○郡△△村」のような表記になっているはずなので。



追記です。
今、テレビを見てて「野々市市」というのがあるというのを知りました。
コードに反映してます。
総務省|電子自治体|全国地方公共団体コード」から、「市」の名称で「郡」と「市」が入るものが他にないことは確認しました。
#「郡」も例外的なのがもっとあるんだろうなあ...



追記です。

#「郡」も例外的なのがもっとあるんだろうなあ...

郡の変遷」に 2014年4月1日時点での「郡」の情報がまとめられていて、「郡」の名称に「市」が入るのは、「余市」と「高市」だけっぽいことは確認しました。



更に追記。
面白そうなので、「全国地方公共団体コード」から表引きについてもちょっと考えてみました。
「郡」の情報がないので、「○○郡」を外して「町」や「村」を抽出する前提です。

東京都の「区」と、他の「市」は良いのですが、「町」と「村」には、その前に「郡」がついているようです。
「全国地方公共団体コード」には「郡」の情報がありませんので、表引きをするには先頭一致ではなく中間一致で探すことになります。
中間一致で探す場合にネックになるのが、他の市町村を包含する名前があること。
例えば、「千葉県栄町」と「鳥取県北栄町」や「愛知県東栄町」です。
これをクリアするためには、表の方の名称が長い方から探さなくちゃいけません。
表引きの場合、ハッシュや二分探索を使うと速いんですが、それが使えず、名称の長い順に並べた表を使って線形探索(ありていに言えば、先頭から探す)。
1800近くある表なので、これは遅そうだ、と。

先頭一致で探せばそれなりに速くなると思いますが、その場合には「郡」を切り取らなくちゃいけない。
ちょっと邪魔くさいのが「郡上郡」。
2004年に「郡上市」になったらしいですが。

東京都の「区」と、「市」を先に振り分けて、「郡」を切り取れれば、残りは「町」と「村」。
名称に両方の文字を含むのは、「群馬県玉村町」と「宮城県村田町」のふたつ。
「町」で先に切り出せば良いかな、と思ったら「長崎県大町町」なんてのがある。

というわけで、市町村の一覧を利用する場合には、以下のような手順になりそう。

  1. 東京都で「区」を切り出す
  2. 都道府県を切り取って、先頭一致で表引きで「市」を切り出す
  3. 「郡上郡」を特別扱いにして、「郡」を切り取る
  4. 「大町町」を特別扱いにして、「町」を切り取る
  5. 「村」を切り取る

「町」、「村」の切り取りは、まとめて先頭一致の表引きでも良いでしょう(遅いけど)。

表引きでも、素直に表と照らし合わせるだけでは駄目でヒューリスティックなロジックにならざるを得なし、市区町村のリストは頻繁ではないにしても更新が入りますので使い続けるつもりのプログラムなら保守が必要。
だったら表なんか使わなくても良いかなあ、という印象です。



またまた追記。
表引きにするなら、「読み仮名データの促音・拗音を小書きで表記するもの - zip圧縮形式 日本郵便」を使う方が良さそう。
この一覧の 8列目を抽出して重複を取り除けば

  • 市+区
  • 郡+町
  • 郡+村

の完全なリストが手に入る。
全部で 1894件。
これを長い順に並べ替えて、住所から都道府県を切り取った文字列と先頭一致で比較して一致したら採用。
「郡は要らない」とか「郡の方を採用」は、一覧にある文字列を加工する感じでしょうか。
ロジックは単純になりますね。

# 総務省の「全国地方公共団体コード」の方は 1741 件で、150件ほど差があるのは廃止になったものを一部含んでいるからかな?



追記。

# 総務省の「全国地方公共団体コード」の方は 1741 件で、150件ほど差があるのは廃止になったものを一部含んでいるからかな?

いや、郵便番号の方は「○○市○○区」の表記だからだった。
一部の差異を除いて、ほぼ同じ。
漢字の表記の違いが2件と、「郡」ではなく「島」という表記が 2件(三宅島と八丈島)。
東京都だからだなあ、きっと。



またまた追記です。
郵便番号の一覧をベースに表引きを軽くやってみました。

性能的な問題は、表を作るときに最大の文字数を控えておき、住所から切り出すときには頭から切り取る文字数を、最大文字数からひとつずつ減らして、その度に表(Dictionary オブジェクト)にあるかどうかを確認するというふうに対処しました。
回答に書いた正規表現を使う場合と、実行時間はさほど変わらない感じです。

ただ、ちょっと問題がありまして。
手持ちの 9000件くらいのデータで試してみたんですが、250件くらいが引き当てできていません。
幾つかサンプリングして調べてみると、以下のようなパターンが。

  • 「町」が「市」になった
  • いくつかの「町」、「村」が合併して市になった
  • 政令指定都市になり、「区」が入った

良くも悪くも入手できる一覧は最新なので、市区町村を切り出す対象の住所に古いものが含まれると、取りこぼしがありそうです。
ぼくが試したデータでは 2.8% を取りこぼしているので、プログラムで切り出した方が例外が少ないという結果になります。
一覧表のデータは、プログラムで切り出した値の検算に使うのが良いかな、という気がしました。

他3件のコメントを見る
id:a-kuma3

2つだけ、

東京都西多摩郡瑞穂町大字高根×××
東京都西多摩郡瑞穂町大字箱根ケ崎×××
(※)×は数字

が空白セルでしたが、

手元のプログラムでは直してたんですが、回答に反映するのを忘れてました (^^;
もし、次に使うことがあるようでしたら、以下の「★」をつけたところを追加・修正してください。

    Set re_z = CreateObject("VBScript.RegExp")
    Dim re_c(10)            ' ★
    For i = 0 To 10         ' ★
        Set re_c(i) = CreateObject("VBScript.RegExp")
    Next

    ...

    re_c(5).Pattern = "^([^村]+村)"
    re_c(6).Pattern = "^([^区]+区)"     ' 東京都用
    re_c(7).Pattern = "^([^市]+市)"     ' 東京都用
    re_c(8).Pattern = "^([^郡]+郡)"     ' 東京都用  ' ★
    re_c(9).Pattern = "^([^町]+町)"     ' 東京都用  ' ★
    re_c(10).Pattern = "^([^村]+村)"    ' 東京都用  ' ★
    
    ...
        If Z = "東京都" Then
            i_begin = 6
            i_end = 10          ' ★
        End If

# 最近、プログラムでやり取りすることが滅多にないので、とても楽しかった :-)

2016/11/19 18:04:51
id:moon-fondu

ありがとうございます。楽しんでいただいて光栄です。またよろしくお願いしますm(__)m

2016/11/20 11:48:18
id:tobeoscontinue No.3

回答回数220ベストアンサー獲得回数59

ポイント500pt

形態素解析を使ってみてはどうでしょう。
http://tech.gmodecorp.com/post/121092256636/mecab
EXCELから使えるものもあるようですがいずれにしろVBAなどscriptが必要になると思います。

形態素解析器はいくつかあるようですがmecabで試してみました。
サンプルとして
東京都港区芝公園4丁目2-8
福島県安達郡大玉村玉井字長久保68
岐阜県山県市大森
山形県南陽市郡山
大阪府交野市郡津
山口県山口市小郡
鹿児島県鹿児島市郡元町
奈良県高市郡
北海道余市郡
をmecabの分かち書きすると
東京 都 港 区 芝公園 4 丁目 2 - 8
福島 県 安達 郡 大玉 村 玉井 字 長久保 6 8
岐阜 県 山県 市 大森
山形 県 南陽 市 郡山
大阪 府 交野 市 郡津
山口 県 山口 市 小郡
鹿児島 県 鹿児島 市 郡元 町
奈良 県 高市 郡
北海道 余市 郡
のようになります。
感じとしては空白で区切られた三番目と四番目のものを使えば
市区町村名(区名)のみを抽出することができます。

しかし北海道は北海 道ではないので例外になり面倒なので
やはりscriptを使います。コードが短くてすむrubyで書きました。
require 'natto'

natto = Natto::MeCab.new

while text = ARGF.gets
na = natto.enum_parse(text).map {|n| n}
of = na[1].feature.split(',')[1] == '接尾' ? 2 : 1
puts "#{na[of].surface}#{na[of+1].surface}"
end
実行結果は
港区
安達郡
山県市
南陽市
交野市
山口市
鹿児島市
高市郡
余市郡
となります。例外があると思いますがrubyスクリプトで対応することになるので苦手だと厳しいかもしれません。
mecabは辞書を使って処理しているので希望するものに近い結果を受け取ることができると思います。

他7件のコメントを見る
id:tobeoscontinue

Windowsの場合はrubyのインストールが必要になります。
コマンドプロンプト(ファイル名はcmd.exe)を起動して入力していくことになります。
Macの場合には既にrubyはインストールされていて、Terminalを起動して入力していくことになります。

mecabを使う場合はmecabをインストールして更にmecab-ipadicもインストールが必要です。
Windowsの場合はPATHの設定が必要なります。mecabでは文字符号にも注意が必要です。
rubyからmecabを使うために更にmecab-rubyやnattoのインストールが必要です。
途中で発生するかもしれないトラブルに対処することでようやく使えるようになります。

ハードルは高かったかもしれませんが得るものも大きかったと思い提案しました。
まさか文字列によっては解析が行われないというのは想定外でしたorz。

2016/11/23 14:45:10
id:moon-fondu

難しそうですね・・・でもありがとうございます!生活に余裕が出来たら…パソコンいじって試してみます(^^;

2016/11/23 21:59:24
  • id:bnn
    「住所から市区町村を抽出」で検索すると、都道府県以下を取り出す→市区町村を取りだす、の方法でいろいろ出てきます。

    違う方法を試したければ、市区町村名のリストが使えそうですね
    http://www.soumu.go.jp/denshijiti/code.html
  • id:moon-fondu
    コメントありがとうございます。日本の市区町村一覧を知るにはそれでもいけますね。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません