個人的神殿

プログラミング

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

25.
今までは長い文字列を1行ずつリストに入れてそれに対して処理を行っていたのだが、今回の問題は複数行にわたっているため、どうすれば良いのかが分からなかった。一度に複数行に対して正規表現マッチングをするにはどうしたら良いか調べていたら良いモノを見つけた。
qiita.com

re.MULTILINE¶
指定されていると、パターン文字 '^' は文字列の先頭で、および各行の先頭 (各改行の直後) で、マッチします。そしてパターン文字 '$' は文字列の末尾で、および各行の末尾 (各改行の直前) で、マッチします。デフォルトでは、 '^' は文字列の先頭でのみ、'$' は文字列の末尾および文字列の末尾の改行 (もしあれば) の直前でのみマッチします。インラインフラグの (?m) に相当します。
re.DOTALL
'.' 特殊文字を、改行を含むあらゆる文字にマッチさせます。このフラグがなければ、'.' は、改行 以外の あらゆる文字とマッチします。インラインフラグの (?s) に相当します。

lines = text.split("\n")
match = re.search(r'(^\{\{基礎情報(.*?)\}\}$)', text, re.MULTILINE+re.DOTALL)
if match:
    print(match.group(0))
{{基礎情報 国
|略名 = イギリス
|日本語国名 = グレートブリテン及び北アイルランド連合王国
|公式国名 = {{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:<br/>
続く…

これを見ると、|フィールド名 = 値 という構造になっているのが分かる。
次にこのmatchを適当なところで分割してリストにして、これまでと同じようにやれば良い。
結果が汚いけどとりあえずまぁいいや。それにしても難しい。

temp_dict = dict()
match = re.search(r"(^\{\{基礎情報(.*?)\}\}$)", text, re.MULTILINE+re.DOTALL)
lines = re.split(r"(\n[\|}])", match.group(0))
for line in lines:
    match2 = re.match(r"((.*?) = (.*))", line, re.DOTALL)
    if match2:
        temp_dict[match2.group(2)] = match2.group(3)

print(temp_dict) 
{'略名': 'イギリス', '日本語国名': 'グレートブリテン及び北アイルランド連合王国', '公式国名': '{{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:<br/>\n*{{lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath}}([[スコットランド・ゲール語]])<br/>\n*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon}}([[ウェールズ語]])<br/>\n*{{lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann}}([[アイルランド語]])<br/>\n*{{lang|kw|An Rywvaneth Unys a Vreten Veur hag Iwerdhon Glédh}}([[コーンウォール語]])<br/>\n*{{lang|sco|Unitit Kinrick o Great Breetain an Northren Ireland}}([[スコットランド語]])<br/>\n**{{lang|sco|Claught Kängrick o Docht Brätain an Norlin Airlann}}、{{lang|sco|Unitet Kängdom o Great Brittain an Norlin Airlann}}(
アルスター・スコットランド語)</ref>', '国旗画像': 'Flag of the United Kingdom.svg', 続く…

26.
一部分だけ変える。
re.subは正規表現にマッチするところを置換(replace)してくれる関数らしい。

if match2:
        temp_dict[match2.group(2)] = re.sub(r"(')", r"()", match2.group(3))

27. 28,
可能な限りキレイにするらしい。
とりあえず思いつくだけやってみた。けっこうキレイになった。

if match2:
        str = re.sub(r"'", r"", match2.group(2))
        str = re.sub(r"<.*?>", r"", str)
        str = re.sub(r"\[", r"", str)
        str = re.sub(r"\]", r"", str)
        str = re.sub(r"\n", r"", str)
        str = re.sub(r"\{", r"", str)
        str = re.sub(r"\}", r"", str)
        str = re.sub(r"\*", r"", str)
        temp_dict[match2.group(1)] = str
{'略名': 'イギリス', '日本語国名': 'グレートブリテン及び北アイルランド連合王国', '公式国名': 'lang|en|United Kingdom
of Great Britain and Northern Ireland英語以外での正式国名:lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath(スコットランド・ゲール語)lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon(ウェールズ語)lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann(アイルランド語)lang|kw|An Rywvaneth Unys a Vreten
Veur hag Iwerdhon Glédh(コーンウォール語)lang|sco|Unitit Kinrick o Great Breetain an Northren Ireland(スコットラン
ド語)lang|sco|Claught Kängrick o Docht Brätain an Norlin Airlann、lang|sco|Unitet Kängdom o Great Brittain an Norlin Airlann(アルスター・スコットランド語)', '国旗画像': 'Flag of the United Kingdom.svg', '国章画像': 'ファイル:Royal
Coat of Arms of the United Kingdom.svg|85px|イギリスの国章', '国章リンク': '(イギリスの国章|国章)', '標語': 'lang|fr|Dieu et mon droit(フランス語:神と私の権利)', '国歌': '女王陛下万歳|神よ女王陛下を守り給え', '位置画像': 'Location_UK_EU_Europe_001.svg', '公用語': '英語(事実上)', '首都': 'ロンドン', '最大都市': 'ロンドン', '元首等肩書': 'イギリ
スの君主|女王', '元首等氏名': 'エリザベス2世', '首相等肩書': 'イギリスの首相|首相', '首相等氏名': 'デーヴィッド・キャ
メロン', '面積順位': '76', '面積大きさ': '1 E11', '面積値': '244,820', '水面積率': '1.3%', '人口統計年': '2011', '人
口順位': '22', '人口大きさ': '1 E7', '人口値': '63,181,775 United Nations Department of Economic and Social Affairs>Population Division>Data>Population>Total Population', '人口密度値': '246', 'GDP統計年元': '2012', 'GDP値元': '1兆5478億 IMF>Data and Statistics>World Economic Outlook Databases>By Countrise>United Kingdom', 'GDP統計年MER': '2012', 'GDP順位MER': '5', 'GDP値MER': '2兆4337億', 'GDP統計年': '2012', 'GDP順位': '6', 'GDP値': '2兆3162億', 'GDP/人': '36,727', '建国形態': '建国', '確立形態1': 'イングランド王国/スコットランド王国(両国とも連合法 (1707年)|1707年連合法まで)
', '確立年月日1': '927年/843年', '確立形態2': 'グレートブリテン王国建国(連合法 (1707年)|1707年連合法)', '確立年月
日2': '1707年', '確立形態3': 'グレートブリテン及びアイルランド連合王国建国(連合法 (1800年)|1800年連合法)', '確立年
月日3': '1801年', '確立形態4': '現在の国号「グレートブリテン及び北アイルランド連合王国」に変更', '確立年月日4': '1927年', '通貨': 'スターリング・ポンド|UKポンド (&pound;)', '通貨コード': 'GBP', '時間帯': '±0', '夏時間': '+1', 'ISO 31
66-1': 'GB / GBR', 'ccTLD': '.uk / .gb使用は.ukに比べ圧倒的少数。', '国際電話番号': '44', '注記': ''}

29. 国旗画像のURLを取得する
テンプレートの内容を利用し,国旗画像のURLを取得せよ.(ヒント: MediaWiki APIのimageinfoを呼び出して,ファイル参照をURLに変換すればよい)

全く意味が分からないですが、とりあえずサンプルコードがあったのでそれを貼り付けてみます。

#This file is auto-generated. See modules.json and autogenerator.py for details

#!/usr/bin/python3

"""
    get_imageinfo.py

    MediaWiki API Demos
    Demo of `Imageinfo` module: Get information about an image file.

    MIT License
"""

import requests

S = requests.Session()

URL = "https://en.wikipedia.org/w/api.php"

PARAMS = {
    "action": "query",
    "format": "json",
    "prop": "imageinfo",
    "titles": "File:Billy_Tipton.jpg"
}

R = S.get(url=URL, params=PARAMS)
DATA = R.json()

PAGES = DATA["query"]["pages"]

for k, v in PAGES.items():
    print(v["title"] + " is uploaded by User:" + v["imageinfo"][0]["user"])
File:Billy Tipton.jpg is uploaded by User:Gobonobo


調べても正直ワケが分からないので、とりあえず保留ということで許してください。