言語処理100本ノック 2015 第3章 20〜24

言語処理100本ノック 2015」の「第3章: 正規表現」、20〜24。

20. JSONデータの読み込み

Wikipedia記事のJSONファイルを読み込み,「イギリス」に関する記事本文を表示せよ.問題21-29では,ここで抽出した記事本文に対して実行せよ

ファイル名と国名を受け取り、指定国名に関する記事本文を表示する関数を書いてみました。

import gzip
import json


def get_article(file, name):
    with gzip.open(file, 'rt') as f:
        for line in f:
            dic = json.loads(line)

            if dic["title"] == name:
                return dic["text"]

gzip.openでgzファイルを開いて、json.loadsで読み込み、titleがnameのtextを返す、という関数です。
呼び出し元からnameとして「イギリス」を渡すことで期待の動作をします。

21. カテゴリ名を含む行を抽出

記事中でカテゴリ名を宣言している行を抽出せよ.

カテゴリ名は「[[Category:イギリス|*]]」という形で出てくるので、正規表現を使って該当行を抽出します。

import re


def get_categorylines(article):
    regex = re.compile(r'\[\[Category:.*\]\]')
    return (l for l in article.splitlines() if regex.search(l))

正規表現内では、バックスラッシュをバックスラッシュとして記載したいのでr”文字列にしています。
splitlinesを使って1行ずつのリストにした上で、re.searchでマッチする行に絞り込んでいます。

22. カテゴリ名の抽出

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

21のget_categorylines関数をちょっと改造。

import re


def get_categories(article):
    regex = re.compile(r'\[\[Category:([^|]+)(\|.*)?\]\]')
    return (m.group(1) for m
            in (regex.search(l) for l in article.splitlines()) if m)

二重のジェネレータ式になっているけど、このアプローチが正しいのか今ひとつ…。

23. セクション構造

記事中に含まれるセクション名とそのレベル(例えば”== セクション名 ==”なら1)を表示せよ.

「== セクション名 ==」「=== セクション名 ===」という形式らしいです。
関数の作りとしては22のget_categoriesと同じ構造でいけますね。

import re


def get_sections(article):
    regex = re.compile(r'(={2,6})\s*(.+?)\s*\1')
    return ((m.group(2), len(m.group(1)) - 1) for m
            in (regex.search(l) for l in article.splitlines()) if m)

24. ファイル参照の抽出

記事から参照されているメディアファイルをすべて抜き出せ.

「ファイル:ファイル名」という形式らしいです。
関数の作りとしてはこれも22のget_categoriesと同じ構造でいけますね。

import re


def get_filereferences(article):
    regex = re.compile(r'ファイル:(.+?)\|')
    return (m.group(1) for m
            in (regex.search(l) for l in article.splitlines()) if m)

とりあえず今回はこのあたりで。

スポンサーリンク

フォローする

スポンサーリンク