言語処理100本ノック2020解いてみた③ 後編


 完全に別タスクが割り込んでしまい、先を解いていない状態なのですが、粛々と前回の続きです。ところでsidecarのご機嫌はまだ直りません。

25. テンプレートの抽出

解法
ちょっと冗長になってしまいました。<ref>系とか<br />系を取り除こうとしたらどうしても長ったらしくなってしまいましたね。

import pandas as pd
import re

df = pd.read_json("data/jawiki-country.json", lines=True)
text = df[df.title=="イギリス"].text.values[0]
text_list = text.split("\n")

table = False
ans = {}
for line in text_list:
	if table:
		if re.match(r"\}\}",line):
			table = False
		if re.match(r"\|(.+?)=(.+?)",line):
			line = re.sub(r"<ref(\s|>).+?(</ref>|$)|<br />","",line)
			for key, value in re.findall(r"\|(.+?)[= ]+(.+)",line):
				ans[key] = value
	elif re.match(r"\{\{基礎情報",line):
		table = True

for key in ans:
	print(key,":",ans[key])

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

解法
以下のような処理をするため、事前にreplaceで置換しておきました。

'''aaa''' -> aaa
import pandas as pd
import re

df = pd.read_json("data/jawiki-country.json", lines=True)
text = df[df.title=="イギリス"].text.values[0]
text_list = text.split("\n")

table = False
ans = {}
for line in text_list:
	if table:
        # 強調マークアップ削除 '''aaa''' -> aaa
		line = line.replace("'''","")

		if re.match(r"\}\}",line):
			table = False	
		if re.match(r"\|(.+?)=(.+?)",line):
			line = re.sub(r"<ref(\s|>).+?(</ref>|$)|<br />","",line)
			for key, value in re.findall(r"\|(.+?)[= ]+(.+)",line):
				ans[key]=value
	elif re.match(r"\{\{基礎情報",line):
		table = True

for key in ans:
	print(key,":",ans[key])

27. 内部リンクの除去

解法
以下のような置換を行うコードを差し込みました。

[[aaa]] or [[aaa|bbb]] or [[aaa|bbb|ccc]] -> aaa
import pandas as pd
import re

df = pd.read_json("data/jawiki-country.json", lines=True)
text = df[df.title=="イギリス"].text.values[0]
text_list = text.split("\n")

table = False
ans = {}
for line in text_list:
	if table:
        # 強調マークアップ削除 '''aaa''' -> aaa
		line = line.replace("'''","")
		# 内部リンク削除: [[aaa]],[[aaa|bbb]],[[aaa|bbb|ccc]] -> aaa
		for l in re.findall(r'(\[\[)([^\|]+?)(\|+[^|]*\|*[^|]+\|*[^|]*)?(\]\])',line):
			line = line.replace("".join(l),l[1])

		if re.match(r"\}\}",line):
			table = False	
		if re.match(r"\|(.+?)=(.+?)",line):
			line = re.sub(r"<ref(\s|>).+?(</ref>|$)|<br />","",line)
			for key, value in re.findall(r"\|(.+?)[= ]+(.+)",line):
				ans[key]=value
	elif re.match(r"\{\{基礎情報",line):
		table = True

for key in ans:
	print(key,":",ans[key])

28. MediaWikiマークアップの除去

解法
気になるマークアップとして、海外記事リンクとかかなと思って取ったんですがこのままだと無限findallをして地獄そう・・・自分のやっていた方針だとここらが限界そうです。

import pandas as pd
import re

df = pd.read_json("data/jawiki-country.json", lines=True)
text = df[df.title=="イギリス"].text.values[0]
text_list = text.split("\n")

table = False
ans = {}
for line in text_list:
	if table:
		# 強調マークアップ削除 '''aaa''' -> aaa
		line = line.replace("'''","")
		# 内部リンク削除: [[aaa]],[[aaa|bbb]],[[aaa|bbb|ccc]] -> aaa
		for l in re.findall(r'(\[\[)([^\|]+?)(\|+[^|]*\|*[^|]+\|*[^|]*)?(\]\])',line):
			line = line.replace("".join(l),l[1]).replace("ファイル:","")
		# 海外記事リンク削除	
		for l in re.findall(r'(\{\{lang\|[a-z]+\|)([^\|]+?)(\}\})',line):
			line = line.replace("".join(l),l[1])

		if re.match(r"\}\}",line):
			table = False
		if re.match(r"\|(.+?)=(.+?)",line):
			line = re.sub(r"<ref(\s|>).+?(</ref>|$)|<br />|\{\{[0-9]\}\}","",line)
			for key, value in re.findall(r"\|(.+?)[= ]+(.+)",line):
				ans[key]=value
	elif re.match(r"\{\{基礎情報",line):
		table = True

for key in ans:
	print(key,":",ans[key])

先人の良さそうな解法を参考にして、拡張されていく先を見通して書かないといかんなと言う反省をいたしました。

29. 国旗画像のURLを取得する

解法
wikiのAPI使用を理解する〜って感じでした。

import pandas as pd
import re
import requests

def get_imgURL(img_filename):
	img_filename = img_filename.replace(" ","_")
	PARAMS = {
	    "action": "query",
	    "format": "json",
	    "prop": "imageinfo",
	    "iiprop":"url",
	    "titles": "File:%s"%img_filename
	}
	S = requests.Session()
	URL = "https://commons.wikimedia.org/w/api.php"
	R = S.get(url=URL, params=PARAMS)
	DATA = R.json()
	PAGES = DATA["query"]["pages"]
	url_list = []
	for k, v in PAGES.items():
		url_list.append(v["imageinfo"][0]["url"])
	return url_list

df = pd.read_json("data/jawiki-country.json", lines=True)
text = df[df.title=="イギリス"].text.values[0]
text_list = text.split("\n")
table = False
ans = {}
for line in text_list:
	if table:
		# 強調マークアップ削除 '''aaa''' -> aaa
		line = line.replace("'''","")
		# 内部リンク削除: [[aaa]],[[aaa|bbb]],[[aaa|bbb|ccc]] -> aaa
		for l in re.findall(r'(\[\[)([^\|]+?)(\|+[^|]*\|*[^|]+\|*[^|]*)?(\]\])',line):
			line = line.replace("".join(l),l[1])
		# 海外記事リンク削除	
		for l in re.findall(r'(\{\{lang\|[a-z]+\|)([^\|]+?)(\}\})',line):
			line = line.replace("".join(l),l[1])
		
		if re.match(r"\}\}",line):
			table = False
     if re.match(r"\|(.+?)=(.+?)",line):
			line = re.sub(r"<ref(\s|>).+?(</ref>|$)|<br />","",line)
			for key, value in re.findall(r"\|(.+?)[= ]+(.+)",line):
				ans[key]=value
	elif re.match(r"\{\{基礎情報",line):
		table = True

print(get_imgURL(ans["国旗画像"]))

感想

正規表現はちょいちょい利用するもののその都度ググりをキメていたので、今回もめちゃくちゃにググりをして改めて勉強することが多いと思いました。さらっと一発で書きたいですね。

創作活動及び成果の発信などの形でみなさんにお返しできたらと思います。