schedule2019-01-22

22. カテゴリ名の抽出

はじめに

言語処理100本ノック 2015

Pythonを勉強するため、東京工業大学の岡崎教授が出題されている言語処理100本ノック 2015を解いていきます。

より深く理解するため、別解や利用したライブラリの解説もまとめていきます。

約半年ぶりに再開しました。 コツコツ勉強できる人になりたい。

環境

Python3.6

OS : mac
3章からWikiを解析する問題になっています。

問題

Wikipediaの記事を以下のフォーマットで書き出したファイルjawiki-country.json.gzがある.

  • 1行に1記事の情報がJSON形式で格納される
  • 各行には記事名が"title"キーに,記事本文が"text"キーの辞書オブジェクトに格納され,そのオブジェクトがJSON形式で書き出される
  • ファイル全体はgzipで圧縮される
    以下の処理を行うプログラムを作成せよ.

22. カテゴリ名の抽出 記事のカテゴリ名を(行単位ではなく名前で)抽出せよ

Point

  • ファイルの読み込み、イギリスの記事抽出は20と同じ。
  • カテゴリ行の抽出は21と同じ。
  • カテゴリ行からカテゴリ名を取り出す方法を考える

解答:Python

正規表現で()は中身を取り出すことができます。 Pythonのre.match()関数では()で抽出した箇所の文字列を得ることができます。

Source code

import gzip
import json
import re


def read_wiki(fname, tiltle):
    with gzip.open(fname, 'rt') as data_file:
        for line in data_file:
            data_json = json.loads(line)
            if data_json['title'] == 'イギリス':
                return data_json['text']


def is_category(string):
    return re.match(r'^\[\[Category:.+\]\]$', string)


def get_category_name(string):
    # カテゴリ名の抽出
    m = re.match(r'^\[\[Category:(.*)\]\]$', string)
    # m.group(1) => 'category_name' or 'category_name|sort_key'
    return m.group(1).split('|')[0]


if __name__ == '__main__':
    fname = 'jawiki-country.json.gz'
    text = read_wiki(fname, 'イギリス').split('\n')

    # カテゴリの行を表示する
    for line in text:
        if is_category(line):
            print(get_category_name(line))

出力

$ python 22.\ カテゴリ名の抽出.py
イギリス
英連邦王国
G8加盟国
欧州連合加盟国
海洋国家
君主国
島国
1801年に設立された州・地域

解説

m = re.match(r'^\[\[Category:(.*)\]\]$', string) の箇所でm.group(1)'category_name'または'category_name|sort_key'となっています。 そこで、|で文字列を分割して先頭の文字列をカテゴリー名として取り出します。

次の記事

Python3で言語処理100本ノックまとめ

前の問題:21. カテゴリ名を含む行を抽出

次の問題:23. セクション構造