言語処理100本ノック 2020をやってみる 第三章:正規表現 前編

#目的
下記のウェブサイトの言語処理100本ノックを行う．

https://nlp100.github.io/ja/

第一章

https://qiita.com/t-baba-11/items/f230136058a695c7c7d1

#第3章:正規表現 
第二章はプログラムではないため割愛．

プログラミング言語はPythonを用いる．
jupyter notebookを使用しているので，出力にprint文が必要な場合は適宜追加する．


データのダウンロード

```.py
import requests
url='https://nlp100.github.io/data/jawiki-country.json.gz'
filename='jawiki-country.json.gz'
urldata = requests.get(url).content
with open(filename ,mode='wb') as f:
    f.write(urldata)
```

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

pandasのDataframeを使いJsonファイルを読み込む．
titleがイギリスである行のtextだけを配列として出力

```.py
import pandas as pd
df = pd.read_json(filename, lines=True)
text = df[df["title"] == "イギリス"]["text"].values
>>>array(['{{redirect|UK}}\n{{redirect|英国|春秋時代の諸侯国|....'])
```

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

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

正規表現を使いCategory:を含む行の見抽出する．
.は任意の文字を表す．
*は直前の文字が0回以上出現することを表す．
すなわち，.*は任意の文字が0回以上出現することに相当する．

```.py
import re
[x for x in text[0].split() if re.match(r'.*Category:.*', x)]
>>>['Kingdom|s=Category:イギリス|n=Category:イギリス|voy=United',
 '[[Category:イギリス|*]]',
 '[[Category:イギリス連邦加盟国]]',
 '[[Category:英連邦王国|*]]',
 '[[Category:G8加盟国]]',
 '[[Category:欧州連合加盟国|元]]',
 '[[Category:海洋国家]]',
 '[[Category:現存する君主国]]',
 '[[Category:島国]]',
 '[[Category:1801年に成立した国家・領域]]']
```



###22. カテゴリ名の抽出
記事のカテゴリ名を（行単位ではなく名前で）抽出せよ．

正規表現を使い，findallで各行のカテゴリの部分のみ抽出する．
その後でsum関数でフラット化．
lstripで不要部分を除去しカテゴリ名を抽出する．
カテゴリ名の重複を除去．
+は直前の文字が1回以上現れることに相当する．
[]内の正規表現は下記のどれか一文字に相当．
ぁ-ん : ひらがな
ァ-ヶ : カタカナ
ｱ-ﾝﾞﾟ : 半角カタカナ
一-龠 : 感じ
a-z   : アルファベット小文字
A-Z   : アルファベット大文字
0-9   : 数字

```.py
set([x.lstrip("Category:") for x in re.findall(r'Category:[ぁ-んァ-ヶｱ-ﾝﾞﾟ一-龠・a-zA-Z0-9]+', text[0])])
>>>{'1801年に成立した国家・領域',
 'G8加盟国',
 'イギリス',
 'イギリス連邦加盟国',
 '島国',
 '欧州連合加盟国',
 '海洋国家',
 '現存する君主国',
 '英連邦王国'}
```

###23. セクション構造
記事中に含まれるセクション名とそのレベル（例えば"== セクション名 =="なら1）を表示せよ．

正規表現でセクションを抽出．
=の数がセクションレベルに紐づいており，
セクション名の前後に=がセクションレベルの数だけあるため
カウントしてセクション名とともに表示．


```.py
[(x.strip("="), int(x.count("=")/2)) for x in re.findall(r'=+[ぁ-んァ-ヶｱ-ﾝﾞﾟ一-龠・a-zA-Z0-9]+=+', text[0])]
>>>[('国名', 2),
 ('歴史', 2),
 ('地理', 2),
 ('主要都市', 3),
 ('気候', 3),
 ('政治', 2),
 ('元首', 3),
 ('法', 3),
 ('内政', 3),
 ('地方行政区分', 3),
 ('外交・軍事', 3),
 ('経済', 2),
 ('鉱業', 3),
 ('農業', 3),
 ('貿易', 3),
 ('不動産', 3),
 ('通貨', 3),
 ('企業', 3),
 ('通信', 4),
 ('交通', 2),
 ('道路', 3),
 ('鉄道', 3),
 ('海運', 3),
 ('航空', 3),
 ('科学技術', 2),
 ('国民', 2),
 ('言語', 3),
 ('宗教', 3),
 ('婚姻', 3),
 ('移住', 3),
 ('教育', 3),
 ('医療', 3),
 ('文化', 2),
 ('食文化', 3),
 ('文学', 3),
 ('哲学', 3),
 ('音楽', 3),
 ('映画', 3),
 ('コメディ', 3),
 ('国花', 3),
 ('世界遺産', 3),
 ('祝祭日', 3),
 ('クリケット', 4),
 ('競馬', 4),
 ('野球', 4),
 ('脚注', 2),
 ('関連項目', 2),
 ('外部リンク', 2)]
```


###24. ファイル参照の抽出

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

"ファイル:"という部分でファイルを参照しているため，
正規表現を使い"ファイル:"の後最短で"."が出現し，アルファベット3文字または4文字が続くという表現を作成．
正規表現にマッチするすべての部分を抽出する．
最後に不要な"ファイル:"を除去し，表示．
?は最短マッチということを表す．最初に出現するパターンでマッチするようになる．
例えば，"abcd.efgh.ijkl"という文字列に対して，".*?\."の場合，"abcd."にマッチする．
".*\."の場合，"abcd.efgh."にマッチする．
{3,4}は最低3回以上，最大4回以下，直前の文字が出現することを表す．最長マッチとなる．

```.py
[x.strip("ファイル:") for x in re.findall(r'ファイル:.+?\.[a-zA-Z]{3,4}', text[0])]
>>>['Royal Coat of Arms of the United Kingdom.svg',
 'United States Navy Band - God Save the Queen.ogg',
 'Descriptio Prime Tabulae Europae.jpg',
 "Lenepveu, Jeanne d'Arc au siège d'Orléans.jpg",
 'London.bank',
 'Battle of Waterloo 1815.PNG',
 'Uk topo en.jpg',
 'BenNevis2005.jpg',
 'Population density UK 2011 census.png',
 '2019 Greenwich Peninsula & Canary Wharf.jpg',
 'Birmingham Skyline from Edgbaston Cricket Ground crop.jpg',
 'Leeds CBD at night.jpg',
 'Glasgow and the Clyde from the air (geograph 4665720).jpg',
 'Palace of Westminster, London - Feb 2007.jpg',
 'Scotland Parliament Holyrood.jpg',
 'Donald Trump and Theresa May (33998675310) (cropped).jpg',
 'Soldiers Trooping the Colour, 16th June 2007.jpg',
 'City of London skyline from London City Hall - Oct 2008.jpg',
 'Oil platform in the North SeaPros.jpg',
 'Eurostar at St Pancras Jan 2008.jpg',
 'Heathrow Terminal 5C Iwelumo-1.jpg',
 'Airbus A380-841 G-XLEB British Airways (10424102995).jpg',
 'UKpop.svg',
 'Anglospeak.svg',
 "Royal Aberdeen Children's Hospital.jpg",
 'CHANDOS3.jpg',
 'The Fabs.JPG',
 'Wembley Stadium, illuminated.jpg']
```