はじめに
言語処理100本ノックというNLPに関する問題集が東京工業大学によって作成、管理されています。
この記事では、「第3章: 正規表現」について回答例を紹介します。
環境設定
Wikipedia の記事を以下のフォーマットで書き出したファイル jawiki-country.json.gz がある.
- 1 行に 1 記事の情報が JSON 形式で格納される
- 各行には記事名が”title”キーに,記事本文が”text”キーの辞書オブジェクトに格納され,そのオブジェクトが JSON 形式で書き出される
- ファイル全体は gzip で圧縮される
以下の処理を行うプログラムを作成せよ.
$ wget https://nlp100.github.io/data/jawiki-country.json.gz
20. JSON データの読み込み
Wikipedia 記事の JSON ファイルを読み込み,「イギリス」に関する記事本文を表示せよ.問題 21-29 では,ここで抽出した記事本文に対して実行せよ.
import pandas as pd
df = pd.read_json('jawiki-country.json.gz', lines=True)
wiki_uk = df.query('title == "イギリス"')['text'].values[0]
print(wiki_uk)
{{redirect|UK}}
{{redirect|英国|春秋時代の諸侯国|英 (春秋)}}
{{Otheruses|ヨーロッパの国|長崎県・熊本県の郷土料理|いぎりす}}
{{基礎情報 国
|略名 =イギリス
|日本語国名 = グレートブリテン及び北アイルランド連合王国
.
.
.
21. カテゴリ名を含む行を抽出
記事中でカテゴリ名を宣言している行を抽出せよ.
import pandas as pd
import re
df = pd.read_json('jawiki-country.json.gz', lines=True)
wiki_uk = df.query('title == "イギリス"')['text'].values[0]
pattern = r'^(.*\[\[Category:.*\]\].*)$'
result = '\n'.join(re.findall(pattern, wiki_uk, re.MULTILINE))
print(result)
[[Category:イギリス|*]]
[[Category:イギリス連邦加盟国]]
[[Category:英連邦王国|*]]
[[Category:G8加盟国]]
[[Category:欧州連合加盟国|元]]
[[Category:海洋国家]]
[[Category:現存する君主国]]
[[Category:島国]]
[[Category:1801年に成立した国家・領域]]
22. カテゴリ名の抽出
記事のカテゴリ名を(行単位ではなく名前で)抽出せよ.
import pandas as pd
import re
df = pd.read_json('jawiki-country.json.gz', lines=True)
wiki_uk = df.query('title == "イギリス"')['text'].values[0]
pattern = r'^.*\[\[Category:(.*?)(?:\|.*)?\]\].*$'
result = '\n'.join(re.findall(pattern, wiki_uk, re.MULTILINE))
print(result)
イギリス
イギリス連邦加盟国
英連邦王国
G8加盟国
欧州連合加盟国
海洋国家
現存する君主国
島国
1801年に成立した国家・領域
23. セクション構造
記事中に含まれるセクション名とそのレベル(例えば”== セクション名 ==”なら 1)を表示せよ.
import pandas as pd
import re
df = pd.read_json('jawiki-country.json.gz', lines=True)
wiki_uk = df.query('title == "イギリス"')['text'].values[0]
pattern = r'^(\={2,})\s*(.+?)\s*(\={2,}).*$'
result = '\n'.join(i[1] + ':' + str(len(i[0]) - 1) for i in re.findall(pattern, wiki_uk, re.MULTILINE))
print(result)
国名:1
歴史:1
地理:1
.
.
.
脚注:1
関連項目:1
外部リンク:1
24. ファイル参照の抽出
記事から参照されているメディアファイルをすべて抜き出せ.
import pandas as pd
import re
df = pd.read_json('jawiki-country.json.gz', lines=True)
wiki_uk = df.query('title == "イギリス"')['text'].values[0]
pattern = r'\[\[ファイル:(.+?)\|'
result = '\n'.join(re.findall(pattern, wiki_uk))
print(result)
Royal Coat of Arms of the United Kingdom.svg
Descriptio Prime Tabulae Europae.jpg
Lenepveu, Jeanne d'Arc au siège d'Orléans.jpg
.
.
.
CHANDOS3.jpg
The Fabs.JPG
Wembley Stadium, illuminated.jpg
25. テンプレートの抽出
記事中に含まれる「基礎情報」テンプレートのフィールド名と値を抽出し,辞書オブジェクトとして格納せよ.
import pandas as pd
import re
df = pd.read_json('jawiki-country.json.gz', lines=True)
wiki_uk = df.query('title == "イギリス"')['text'].values[0]
# extract template
pattern = r'^\{\{基礎情報.*?$(.*?)^\}\}'
template = re.findall(pattern, wiki_uk, re.MULTILINE + re.DOTALL)
# get field name and value
pattern = r'^\|(.+?)\s*=\s*(.+?)(?:(?=\n\|)| (?=\n$))'
result = re.findall(pattern, template[0], re.MULTILINE + re.DOTALL)
result = dict(result)
for k, v in result.items():
print(k + ':' + v)
.
.
.
国旗画像:Flag of the United Kingdom.svg
国章画像:[[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]]
国章リンク:([[イギリスの国章|国章]])
標語:{{lang|fr|[[Dieu et mon droit]]}}<br />([[フランス語]]:[[Dieu et mon droit|神と我が権利]])
国歌:[[女王陛下万歳|{{lang|en|God Save the Queen}}]]{{en icon}}<br />''神よ女王を護り賜え''<br />{{center|[[ファイル:United States Navy Band - God Save the Queen.ogg]]}}
地図画像:Europe-UK.svg
位置画像:United Kingdom (+overseas territories) in the World (+Antarctica claims).svg
公用語:[[英語]]
.
.
.
26. 強調マークアップの除去
25 の処理時に,テンプレートの値から MediaWiki の強調マークアップ(弱い強調,強調,強い強調のすべて)を除去してテキストに変換せよ(参考: マークアップ早見表).
import pandas as pd
import re
df = pd.read_json('jawiki-country.json.gz', lines=True)
wiki_uk = df.query('title == "イギリス"')['text'].values[0]
# extract template
pattern = r'^\{\{基礎情報.*?$(.*?)^\}\}'
template = re.findall(pattern, wiki_uk, re.MULTILINE + re.DOTALL)
# get field name and value
pattern = r'^\|(.+?)\s*=\s*(.+?)(?:(?=\n\|)| (?=\n$))'
result = re.findall(pattern, template[0], re.MULTILINE + re.DOTALL)
# remove emphasis
pattern = re.compile(r'\'{2,5}', re.MULTILINE + re.S)
result = {i[0]:pattern.sub('', i[1]) for i in result}
result = dict(result)
for k, v in result.items():
print(k + ':' + v)
.
.
.
国旗画像:Flag of the United Kingdom.svg
国章画像:[[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]]
国章リンク:([[イギリスの国章|国章]])
標語:{{lang|fr|[[Dieu et mon droit]]}}<br />([[フランス語]]:[[Dieu et mon droit|神と我が権利]])
国歌:[[女王陛下万歳|{{lang|en|God Save the Queen}}]]{{en icon}}<br />神よ女王を護り賜え<br />{{center|[[ファイル:United States Navy Band - God Save the Queen.ogg]]}}
地図画像:Europe-UK.svg
位置画像:United Kingdom (+overseas territories) in the World (+Antarctica claims).svg
公用語:[[英語]]
.
.
.
27. 内部リンクの除去
26 の処理に加えて,テンプレートの値から MediaWiki の内部リンクマークアップを除去し,テキストに変換せよ(参考: マークアップ早見表).
import pandas as pd
import re
df = pd.read_json('jawiki-country.json.gz', lines=True)
wiki_uk = df.query('title == "イギリス"')['text'].values[0]
# extract template
pattern = r'^\{\{基礎情報.*?$(.*?)^\}\}'
template = re.findall(pattern, wiki_uk, re.MULTILINE + re.DOTALL)
# get field name and value
pattern = r'^\|(.+?)\s*=\s*(.+?)(?:(?=\n\|)| (?=\n$))'
result = re.findall(pattern, template[0], re.MULTILINE + re.DOTALL)
# remove emphasis
pattern = re.compile(r'\'{2,5}', re.MULTILINE + re.S)
result = {i[0]:pattern.sub('', i[1]) for i in result}
# remove inner link
pattern = r'\[\[(?:[^|]*?\|)??([^|]*?)\]\]'
result = {k: re.sub(pattern, r'\1', v) for k, v in result.items()}
result = dict(result)
for k, v in result.items():
print(k + ':' + v)
.
.
.
国旗画像:Flag of the United Kingdom.svg
国章画像:[[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]]
国章リンク:(国章)
標語:{{lang|fr|Dieu et mon droit}}<br />(フランス語:神と我が権利)
国歌:[[女王陛下万歳|{{lang|en|God Save the Queen}}]]{{en icon}}<br />神よ女王を護り賜え<br />{{center|ファイル:United States Navy Band - God Save the Queen.ogg}}
地図画像:Europe-UK.svg
位置画像:United Kingdom (+overseas territories) in the World (+Antarctica claims).svg
公用語:英語
.
.
.
28. MediaWiki マークアップの除去
27 の処理に加えて,テンプレートの値から MediaWiki マークアップを可能な限り除去し,国の基本情報を整形せよ.
import pandas as pd
import re
df = pd.read_json('jawiki-country.json.gz', lines=True)
wiki_uk = df.query('title == "イギリス"')['text'].values[0]
# extract template
pattern = r'^\{\{基礎情報.*?$(.*?)^\}\}'
template = re.findall(pattern, wiki_uk, re.MULTILINE + re.DOTALL)
# get field name and value
pattern = r'^\|(.+?)\s*=\s*(.+?)(?:(?=\n\|)| (?=\n$))'
result = re.findall(pattern, template[0], re.MULTILINE + re.DOTALL)
# remove emphasis
pattern = re.compile(r'\'{2,5}', re.MULTILINE + re.S)
result = {i[0]:pattern.sub('', i[1]) for i in result}
# remove inner link
pattern = r'\[\[(?:[^|]*?\|)??([^|]*?)\]\]'
result = {k: re.sub(pattern, r'\1', v) for k, v in result.items()}
# remove outer link
pattern = r'https?://[\w!?/\+\-_~=;\.,*&@#$%\(\)\'\[\]]+'
result = {k: re.sub(pattern, '', v) for k, v in result.items()}
# remove html tag
pattern = r'<.+?>'
result = {k: re.sub(pattern, '', v) for k, v in result.items()}
# remove template
pattern = r'\{\{(?:lang|仮リンク)(?:[^|]*?\|)*?([^|]*?)\}\}'
result = {k: re.sub(pattern, r'\1', v) for k, v in result.items()}
result = dict(result)
for k, v in result.items():
print(k + ':' + v)
.
.
.
国旗画像:Flag of the United Kingdom.svg
国章画像:[[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]]
国章リンク:(国章)
標語:Dieu et mon droit(フランス語:神と我が権利)
国歌:[[女王陛下万歳|God Save the Queen]]{{en icon}}神よ女王を護り賜え{{center|ファイル:United States Navy Band - God Save the Queen.ogg}}
地図画像:Europe-UK.svg
位置画像:United Kingdom (+overseas territories) in the World (+Antarctica claims).svg
公用語:英語
.
.
.
29. 国旗画像の URL を取得する
テンプレートの内容を利用し,国旗画像の URL を取得せよ.(ヒント: MediaWiki API の imageinfo を呼び出して,ファイル参照を URL に変換すればよい)
import pandas as pd
import re
import requests
df = pd.read_json('jawiki-country.json.gz', lines=True)
wiki_uk = df.query('title == "イギリス"')['text'].values[0]
# extract template
pattern = r'^\{\{基礎情報.*?$(.*?)^\}\}'
template = re.findall(pattern, wiki_uk, re.MULTILINE + re.DOTALL)
# get field name and value
pattern = r'^\|(.+?)\s*=\s*(.+?)(?:(?=\n\|)| (?=\n$))'
result = re.findall(pattern, template[0], re.MULTILINE + re.DOTALL)
# remove emphasis
pattern = re.compile(r'\'{2,5}', re.MULTILINE + re.S)
result = {i[0]:pattern.sub('', i[1]) for i in result}
# remove inner link
pattern = r'\[\[(?:[^|]*?\|)??([^|]*?)\]\]'
result = {k: re.sub(pattern, r'\1', v) for k, v in result.items()}
# remove outer link
pattern = r'https?://[\w!?/\+\-_~=;\.,*&@#$%\(\)\'\[\]]+'
result = {k: re.sub(pattern, '', v) for k, v in result.items()}
# remove html tag
pattern = r'<.+?>'
result = {k: re.sub(pattern, '', v) for k, v in result.items()}
# remove template
pattern = r'\{\{(?:lang|仮リンク)(?:[^|]*?\|)*?([^|]*?)\}\}'
result = {k: re.sub(pattern, r'\1', v) for k, v in result.items()}
# get url
url_file = result['国旗画像'].replace(' ', '_')
url = 'https://commons.wikimedia.org/w/api.php?action=query&titles=File:' + url_file + '&prop=imageinfo&iiprop=url&format=json'
data = requests.get(url)
print(re.search(r'"url":"(.+?)"', data.text).group(1))
https://upload.wikimedia.org/wikipedia/commons/8/83/Flag_of_the_United_Kingdom_%283-5%29.svg
参考
AlloyDB
Amazon Cognito
Amazon EC2
Amazon ECS
Amazon QuickSight
Amazon RDS
Amazon Redshift
Amazon S3
API
Autonomous Vehicle
AWS
AWS API Gateway
AWS Chalice
AWS Control Tower
AWS IAM
AWS Lambda
AWS VPC
BERT
BigQuery
Causal Inference
ChatGPT
Chrome Extension
CircleCI
Classification
Cloud Functions
Cloud IAM
Cloud Run
Cloud Storage
Clustering
CSS
Data Engineering
Data Modeling
Database
dbt
Decision Tree
Deep Learning
Descriptive Statistics
Differential Equation
Dimensionality Reduction
Discrete Choice Model
Docker
Economics
FastAPI
Firebase
GIS
git
GitHub
GitHub Actions
Google
Google Cloud
Google Search Console
Hugging Face
Hypothesis Testing
Inferential Statistics
Interval Estimation
JavaScript
Jinja
Kedro
Kubernetes
LightGBM
Linux
LLM
Mac
Machine Learning
Macroeconomics
Marketing
Mathematical Model
Meltano
MLflow
MLOps
MySQL
NextJS
NLP
Nodejs
NoSQL
ONNX
OpenAI
Optimization Problem
Optuna
Pandas
Pinecone
PostGIS
PostgreSQL
Probability Distribution
Product
Project
Psychology
Python
PyTorch
QGIS
R
ReactJS
Regression
Rideshare
SEO
Singer
sklearn
Slack
Snowflake
Software Development
SQL
Statistical Model
Statistics
Streamlit
Tabular
Tailwind CSS
TensorFlow
Terraform
Transportation
TypeScript
Urban Planning
Vector Database
Vertex AI
VSCode
XGBoost