言語処理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ポンド]] (£)'), ('通貨コード', '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ポンド]] (£)'), ('通貨コード', '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ポンド (£)'), ('通貨コード', 'GBP'), ('時間帯', '±0'), ('夏時間', '+1'), ('ISO 3166-1', 'GB / GBR'), ('ccTLD', '.uk / .gb<ref>使用は.ukに比べ圧倒的少数。</ref>'), ('国際電話番号', '44')] """
うまく除去できてるっぽい