個人的神殿

プログラミング

言語処理100本ノック 第3章 前半

20.
jsonの読み込みが全然できねぇ、いろいろと試してみたけどそれでもできねぇと思っていたが、
実はダウンロードしたのがgzipファイルというもので、それの解凍をしていなかったというオチだった。

import json

with open("jawiki-country.json", encoding = "utf-8") as fp:
    json_data = json.load(fp)

これで実行してみると、エラーが出た。

json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 27837)

調べたらfor文で1行ずつ読み込まないといけないらしい。

import json

with open("jawiki-country.json", encoding = "utf-8") as fp:
    for i in fp:
        json_data = json.load(i)

これで実行したら、今度はこんなエラーが。

AttributeError: 'str' object has no attribute 'read'

どうやら、json.loadってのはJSONファイル辞書として読み込むためのメソッドで、文字列を辞書として読み込む場合はjson.loadsだった。
今はiを読み込みたいのだが、あぁなるほどこのiは文字列なんだね。JSONについて全然理解できてないな。

ちなみにこのようにして最後の行を取得してみると次のような表示が出た。

import json

with open("jawiki-country.json", encoding = "utf-8") as fp:
    for i in fp:
        json_data = json.loads(i)
print(json_data)
{'text': '#転送 [[アイルランド共和国]]', 'title': 'アイルランド'}

確かに'text',、'title'がキーの辞書だということが分かった。
よし、titleがイギリスであるもののtextを表示させれば終わりだ。

import json

with open("jawiki-country.json", encoding = "utf-8") as fp:
    for i in fp:
        json_data = json.loads(i)
        if json_data["title"] == "イギリス":
            text = json_data["text"]
            print(text)
            break

これでめでたく、textの中にはイギリスに関する本文が格納された。

21.
Categoryという文字列を含んでいるかを調べる。

import re
lines = text.split("\n")
for line in lines:
    match = re.search(r'.*Category.*', line)
    if match:
        print(line)
[[Category:イギリス|*]]
[[Category:英連邦王国|*]]
[[Category:G8加盟国]]
[[Category:欧州連合加盟国]]
[[Category:海洋国家]]
[[Category:君主国]]
[[Category:島国|くれいとふりてん]]
[[Category:1801年に設立された州・地域]]

22.
正規表現の条件部分は()で囲ってグループ化できるらしい。
(|\|.*)というのはちょっと分かりにくいが、(文字無し または |とそれに続く任意個の文字)を表している。
最初の | は、またはを意味している。

そして.?*というのは一応最短マッチと言われているらしいが……こちらのサイトに詳しく書いてある。
qiita.com

import re
lines = text.split("\n")
for line in lines:
    match = re.search(r'(^\[\[Category:(.*?)(|\|.*)\]\])', line)
    if match:
        print(match.group(2))
イギリス
英連邦王国
G8加盟国
欧州連合加盟国
海洋国家
君主国
島国
1801年に設立された州・地域

23.
セクション名の前後に余計なスペースがある場合があったからそれも考えないといけなかった。

lines = text.split("\n")
for line in lines:
    match = re.match(r'((=+)\s*(.*?)\s*(=+))', line)
    if match:
        print(match.group(3), " ", len(match.group(2)) - 1)
国名   1
歴史   1
地理   1
気候   2
政治   1
外交と軍事   1
地方行政区分   1
主要都市   2
科学技術   1
続く...

24.
メディアファイルはファイル:かFile:で始まる文の中にあるのでこのようになった。

lines = text.split("\n")
for line in lines:
    match = re.search(r"(.*(ファイル:|File:)(.*?)\|)", line)
    if match:
        print(match.group(3))
Royal Coat of Arms of the United Kingdom.svg
Battle of Waterloo 1815.PNG
The British Empire.png
Uk topo en.jpg
BenNevis2005.jpg
続く…