yamakiy’s tech blog

技術系の記事をメインにやります。

言語処理100本ノック(第3章 25 ~ 27)

前回の続き

25. テンプレートの抽出

記事中に含まれる「基礎情報」テンプレートのフィールド名と値を抽出し,辞書オブジェクトとして格納せよ.

#!/usr/bin/python3.6
import json
import re
from pprint import pprint

class JawikiCountry(object):
    jawiki = ""

    def __init__(self, country):
        self.jawiki = self.get_jawiki(country)

    def get_jawiki(self, country):
        jawiki_country = {}
        with open("jawiki-country.json", "r") as f:
            for i in f:
                data = json.loads(i)
                jawiki_country[data["title"]] = data["text"]
        return jawiki_country[country]

    def get_basic_info(self):
        basic_info = re.findall(r'^\{\{基礎情報.*?$\n(.*)^\}\}$', self.jawiki,re.MULTILINE + re.DOTALL)[0]
        basic_info = re.findall(r'^\|(.+?)\s*=\s*(.+?)(?=\n\|)', basic_info, re.MULTILINE + re.DOTALL)
        return basic_info

if __name__ == "__main__":
    jc = JawikiCountry("イギリス")
    pprint(jc.get_basic_info())

"""
[('略名', 'イギリス'),
 ('日本語国名', 'グレートブリテン及び北アイルランド連合王国'),
 ('公式国名',
  '{{lang|en|United Kingdom of Great Britain and Northern '
  'Ireland}}<ref>英語以外での正式国名:<br/>\n'
  '*{{lang|gd|An Rioghachd Aonaichte na Breatainn Mhor agus Eirinn mu '
  'Thuath}}([[スコットランド・ゲール語]])<br/>\n'

~~~ 中略 ~~~

 ('確立形態4', "現在の国号「'''グレートブリテン及び北アイルランド連合王国'''」に変更"),
 ('確立年月日4', '[[1927年]]'),
 ('通貨', '[[スターリング・ポンド|UKポンド]] (&pound;)'),
 ('通貨コード', 'GBP'),
 ('時間帯', '±0'),
 ('夏時間', '+1'),
 ('ISO 3166-1', 'GB / GBR'),
 ('ccTLD', '[[.uk]] / [[.gb]]<ref>使用は.ukに比べ圧倒的少数。</ref>'),
 ('国際電話番号', '44')]
"""

肯定先読み(?=)を使うところが分からず、こちらの方の解答を参考にさせていただきました。
qiita.com

正規表現わかってるつもりになってたけど、だいぶ理解が浅かったみたい
難しいなぁ・・・

26. 強調マークアップの除去

25の処理時に,テンプレートの値からMediaWikiの強調マークアップ(弱い強調,強調,強い強調のすべて)を除去してテキストに変換せよ(参考: マークアップ早見表

#!/usr/bin/python3.6
import json
import re
from pprint import pprint

class JawikiCountry(object):
    jawiki = ""

    def __init__(self, country):
        self.jawiki = self.get_jawiki(country)

    def get_jawiki(self, country):
        jawiki_country = {}
        with open("jawiki-country.json", "r") as f:
            for i in f:
                data = json.loads(i)
                jawiki_country[data["title"]] = data["text"]
        return jawiki_country[country]

    def get_basic_info(self):
        basic_info = re.findall(r'^\{\{基礎情報.*?$\n(.*)^\}\}$', self.jawiki,re.MULTILINE + re.DOTALL)[0]
        basic_info = re.findall(r'^\|(.+?)\s*=\s*(.+?)(?=\n\|)', basic_info, re.MULTILINE + re.DOTALL)
        return basic_info

    def get_basic_info_no_markup(self):
        basic_info = self.get_basic_info()
        # \1で判定条件中の(\'{2,5})を利用して数を揃える
        rm_markup = lambda x: re.sub(r'(\'{2,5})(.*?)\1', r'\2', x)
        return [(i[0], rm_markup(i[1])) for i in basic_info]

if __name__ == "__main__":
    jc = JawikiCountry("イギリス")
    pprint(jc.get_basic_info_no_markup())

"""
[('略名', 'イギリス'),
 ('日本語国名', 'グレートブリテン及び北アイルランド連合王国'),
 ('公式国名',
  '{{lang|en|United Kingdom of Great Britain and Northern '
  'Ireland}}<ref>英語以外での正式国名:<br/>\n'
  '*{{lang|gd|An Rioghachd Aonaichte na Breatainn Mhor agus Eirinn mu '
  'Thuath}}([[スコットランド・ゲール語]])<br/>\n'
  '*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd '
  'Iwerddon}}([[ウェールズ語]])<br/>\n'

~~~ 中略 ~~~

 ('確立形態3', '[[グレートブリテン及びアイルランド連合王国]]建国<br />([[連合法 (1800年)|1800年連合法]])'),
 ('確立年月日3', '[[1801年]]'),
 ('確立形態4', '現在の国号「グレートブリテン及び北アイルランド連合王国」に変更'),
 ('確立年月日4', '[[1927年]]'),
 ('通貨', '[[スターリング・ポンド|UKポンド]] (&pound;)'),
 ('通貨コード', 'GBP'),
 ('時間帯', '±0'),
 ('夏時間', '+1'),
 ('ISO 3166-1', 'GB / GBR'),
 ('ccTLD', '[[.uk]] / [[.gb]]<ref>使用は.ukに比べ圧倒的少数。</ref>'),
 ('国際電話番号', '44')]

マークアップされてた行
 ('確立形態4', "現在の国号「'''グレートブリテン及び北アイルランド連合王国'''」に変更"),

('確立形態4', '現在の国号「グレートブリテン及び北アイルランド連合王国」に変更')

27. 内部リンクの除去

26の処理に加えて,テンプレートの値からMediaWikiの内部リンクマークアップを除去し,テキストに変換せよ(参考: マークアップ早見表))

#!/usr/bin/python3.6
import json
import re
from pprint import pprint

class JawikiCountry(object):
    jawiki = ""

    def __init__(self, country):
        self.jawiki = self.get_jawiki(country)

    def get_jawiki(self, country):
        jawiki_country = {}
        with open("jawiki-country.json", "r") as f:
            for i in f:
                data = json.loads(i)
                jawiki_country[data["title"]] = data["text"]
        return jawiki_country[country]

    def get_basic_info(self):
        basic_info = re.findall(r'^\{\{基礎情報.*?$\n(.*)^\}\}$', self.jawiki,re.MULTILINE + re.DOTALL)[0]
        basic_info = re.findall(r'^\|(.+?)\s*=\s*(.+?)(?=\n\|)', basic_info, re.MULTILINE + re.DOTALL)
        return basic_info

    def get_basic_info_no_markup_no_inlink(self):
        basic_info = self.get_basic_info()
        rm_markup = lambda x: re.sub(r'(\'{2,5})(.*?)\1', r'\2', x)
        rm_inlink = lambda x: re.sub(r'\[\[(?!Category:|File:|ファイル:)(.*?)\]\]', r'\1', x)
        res = []
        for line in basic_info:
            val = rm_markup(line[1])
            val = rm_inlink(val)
            res += [(line[0], val)]
        return res

if __name__ == "__main__":
    jc = JawikiCountry("イギリス")
    pprint(jc.get_basic_info_no_markup())

"""
[('略名', 'イギリス'),
 ('日本語国名', 'グレートブリテン及び北アイルランド連合王国'),
 ('公式国名',
  '{{lang|en|United Kingdom of Great Britain and Northern '
  'Ireland}}<ref>英語以外での正式国名:<br/>\n'
  '*{{lang|gd|An Rioghachd Aonaichte na Breatainn Mhor agus Eirinn mu '
  'Thuath}}(スコットランド・ゲール語)<br/>\n'

~~~ 中略 ~~~

 ('確立年月日2', '1707年'),
 ('確立形態3', 'グレートブリテン及びアイルランド連合王国建国<br />(連合法 (1800年)|1800年連合法)'),
 ('確立年月日3', '1801年'),
 ('確立形態4', '現在の国号「グレートブリテン及び北アイルランド連合王国」に変更'),
 ('確立年月日4', '1927年'),
 ('通貨', 'スターリング・ポンド|UKポンド (&pound;)'),
 ('通貨コード', 'GBP'),
 ('時間帯', '±0'),
 ('夏時間', '+1'),
 ('ISO 3166-1', 'GB / GBR'),
 ('ccTLD', '.uk / .gb<ref>使用は.ukに比べ圧倒的少数。</ref>'),
 ('国際電話番号', '44')]
"""

うまく除去できてるっぽい