【python】100本ノックにチャレンジ!(025〜029)

#これまでの経緯などについて
[最初の投稿](http://qiita.com/masassy/items/6e25c0adc4ef7c8bf4fc)を参照ください

#[ノック状況](https://qiita.com/masassy/items/6f022af11dfdc16b9cea)
9/24追加

#第3章: 正規表現

Wikipediaの記事を以下のフォーマットで書き出したファイルjawiki-country.json.gzがある．
・1行に1記事の情報がJSON形式で格納される
・各行には記事名が"title"キーに，記事本文が"text"キーの辞書オブジェクトに格納され，そのオブジェクトがJSON形式で書き出される
・ファイル全体はgzipで圧縮される
以下の処理を行うプログラムを作成せよ．

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

```python:basic_info_025.py
from training.json_read_020 import uk_find
import re

def basic_info_find(lines):
    pattern1 = re.compile(r'^\{\{[redirect|基礎情報].*')
    pattern2 = re.compile(r'^\|.*')
    pattern3 = re.compile(r'^\}\}$')

    basic_dict = {}
    for line in lines.split('\n'):
        if pattern1.match(line):
            continue

        elif pattern2.match(line):
            point = line.find('=')
            MAX = len(line)
            title = line[0:point].lstrip('|').rstrip(' ')
            data = line[point:MAX].lstrip('= ')
            basic_dict.update({title: data})

        elif pattern3.match(line):
            break
    return basic_dict

if __name__=="__main__":
    lines = uk_find()
    basic_dict = basic_info_find(lines)
    for key,value in basic_dict.items():
        print(key+':'+value)

```
```text:result
確立形態4:現在の国号「'''グレートブリテン及び北アイルランド連合王国'''」に変更
国章画像:[[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]]
国章リンク:（[[イギリスの国章|国章]]）
(長いので略)
Process finished with exit code 0
```
感想：基礎情報の結果から|で始まる行を抜き出し、＝の前後で辞書のkeyとvalueへ格納するループを回した。printの結果は分かりやすいように加工した。

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

```python:emphasize_remove_026.py
from training.json_read_020 import uk_find
from training.basic_info_025 import basic_info_find
import re

def emphasize_remove(basic_dict):
    pattern = re.compile(r".*'{2,4}.*")
    for key,value in basic_dict.items():
        if pattern.match(value):
            value = value.replace("\'",'')
            basic_dict.update({key:value})
    return basic_dict


if __name__ == "__main__":
    lines = uk_find()
    basic_dict = basic_info_find(lines)
    emphasize_remove_dict = emphasize_remove(basic_dict)
    for key,value in emphasize_remove_dict.items():
        print(key+':'+value)

```
```text:result
GDP統計年元:2012
確立形態4:現在の国号「グレートブリテン及び北アイルランド連合王国」に変更
面積大きさ:1 E11
(長いので略)
Process finished with exit code 0
```
感想：該当箇所が1箇所しかなかったが、強調マークアップを全て検索できるように'{2,4}としている。見つけたらreplaceで置き換えしただけ。

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

```python:link_remove_027.py
from training.json_read_020 import uk_find
from training.basic_info_025 import basic_info_find
from training.emphasize_remove_026 import emphasize_remove
import re

def link_remove(emphasize_remove_dict):
    pattern = re.compile(r".*\[{2}.*")
    for key,value in emphasize_remove_dict.items():
        if pattern.match(value):
            value = value.replace('[[','').replace(']]','')
            emphasize_remove_dict.update({key: value})
    return emphasize_remove_dict

if __name__=="__main__":
    lines = uk_find()
    basic_dict = basic_info_find(lines)
    emphasize_remove_dict=emphasize_remove(basic_dict)
    link_remove_dict = link_remove(emphasize_remove_dict)

    for key,value in link_remove_dict.items():
        print(key+':'+value)

```
```text:result
国章画像:ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章
公式国名:{{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:<br/>
建国形態:建国
(長いので略)
Process finished with exit code 0
```
感想：026の問題に似ていて[[から始まる内部リンク部分を見つけたら[[と]]をreplaceで置き換えしただけ。


#028. MediaWikiマークアップの除去
27の処理に加えて，テンプレートの値からMediaWikiマークアップを可能な限り除去し，国の基本情報を整形せよ．

```python:markup_remove_028.py
from training.json_read_020 import uk_find
from training.basic_info_025 import basic_info_find
from training.emphasize_remove_026 import emphasize_remove
from training.link_remove_027 import link_remove
import re

#poundを除去する関数。
def pound_check(value):
    pattern = re.compile(r".*pound.*")
    if pattern.match(value):
        value = value.replace("(&pound;)",'')
        return value
    else:
        return  value

#brタグを除去する関数。
def br_check(value):
    pattern1 = re.compile(r".*<br.*")
    if pattern1.match(value):
        value = value.replace("<br />", '').replace("<br/>", '')
        return value
    else:
        return value

#refタグとreference記述を除去する関数。
def ref_check(value):
    pattern2 = re.compile(r".*<ref.*")
    if pattern2.match(value):
        start_point = value.find("<ref")
        value = value[0:start_point]
        return value
    else:
        return value

#{{と}}を除去する関数。
def brackets_check(value):
    pattern3 = re.compile(r".*\{\{.*")
    if pattern3.match(value):
        value = value.replace("{{","").replace("}}","")
        #lang|en|United〜とした場合に最初のパイプから4文字以降を取得#
        start_point = value.find("|")+4
        value = value[start_point:len(value)]
        return value
    else:
        return value

#ファイル：除去する関数。
def file_check(value):
    pattern4 = re.compile(r".*ファイル.*")
    if pattern4.match(value):
        value = value.replace('ファイル:','')
        start_point = value.find("|")
        value = value[0:start_point]
        return value
    else:
        return value

#半角の|を除去する関数。|のみと|+()が存在するパターンを除去。
def pipe_check(value):
     pattern5 = re.compile(r".*\|.*")
     pattern6 = re.compile(r".*\(.*")
     if pattern5.match(value) and pattern6.match(value) :
         end_point = value.find("|")
         value = value[0:end_point] + ")"
         return value
     elif pattern5.match(value):
         end_point = value.find("|")
         value = value[0:end_point]
         return value
     else:
         return value

#全角の（を除去する関数
def other_check(value):
    pattern7 = re.compile(r"^\（")
    if pattern7.match(value):
        value = value.replace("（","")
        return value
    else:
        return value

def markup_remove(link_remove_dict):
    for key,value in link_remove_dict.items():
        value = pound_check(value)
        value = br_check(value)
        value = ref_check(value)
        value = brackets_check(value)
        value = file_check(value)
        value = pipe_check(value)
        value = other_check(value)
        link_remove_dict.update({key:value})

    return link_remove_dict


if __name__=="__main__":
    lines = uk_find()
    basic_dict = basic_info_find(lines)
    emphasize_remove_dict=emphasize_remove(basic_dict)
    link_remove_dict = link_remove(emphasize_remove_dict)
    markup_remove_dict = markup_remove(link_remove_dict)

    for key,value in markup_remove_dict.items():
        print(key+':'+value)

    print(len(markup_remove_dict.items()))

```
```text:result
確立年月日1:927年／843年
公式国名:United Kingdom of Great Britain and Northern Ireland
確立形態1:イングランド王国／スコットランド王国（両国とも連合法 (1707年))
位置画像:Location_UK_EU_Europe_001.svg
標語:Dieu et mon droit（フランス語:神と私の権利）
ccTLD:.uk / .gb
国旗画像:Flag of the United Kingdom.svg
通貨:スターリング・ポンド
(長いので略)
Process finished with exit code 0
```
感想：まずどんなマークアップを引っ掛けるか確認するためにマークアップを見つけてはコンパイルパターンを作ってを繰り返した。。。そして1行ごとにすべてのパターンで評価することに。しかし、全角表記はナシだろ。。。なんで引っかからないのかすごく悩んだよ。。。疲れたっす。

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

```python:get_url_029.py
# -*- coding:utf-8-*-

from training.json_read_020 import uk_find
from training.basic_info_025 import basic_info_find
import requests
import urllib.parse
import json
import re

def image_query(filename):
    url = "https://commons.wikimedia.org/w/api.php?"
    action = "action=query&"
    titles = "titles=File:"+urllib.parse.quote(filename)+"&"
    prop = "prop=imageinfo&"
    iiprop="iiprop=url&"
    format = "format=json"
    parameter = url +action+titles+prop+iiprop+format
    return parameter

def get_request(parameter):
    pattern = re.compile(r".*\"url\".*")
    r = requests.get(parameter)
    data = r.json()
    json_data =json.dumps(data["query"]["pages"]["347935"]["imageinfo"],indent=4)
    for temp in json_data.split('\n'):
        if(pattern.search(temp)):
            url_data = temp.replace(" ","")
        else:
            continue

    return url_data

if __name__=="__main__":
    lines = uk_find()
    basic_dict = basic_info_find(lines)
    parameter=image_query(basic_dict['国旗画像'])
    get_url = get_request(parameter)
    print(get_url)

```
```text:result
"url":"https://upload.wikimedia.org/wikipedia/commons/a/ae/Flag_of_the_United_Kingdom.svg"

Process finished with exit code 0
```
感想：最初は何をやればいいのかよくわからなかった問題。色々ググってたら要はwikimediaにファイル名に関するデータを検索するリクエストを投げて、レスポンスから画像ファイルがアップされているURLを見つけろということだった。この題意を理解するのにめっちゃ時間かかった、、、色んな意味で勉強になった問題でした。