LoginSignup
0
0

More than 3 years have passed since last update.

言語処理100本ノック2020やってみた part3

Posted at

はじめに

わからないところは他の方の解答見てどうしたらそれに辿りつくのかということをやってます。
29は全くわからないので他の人の見てください、自分で理解できたら書きます。
正規表現はほとんど書いたことないのでコードがかなり汚いです。いづれ直します。
今回は全体的にコードがひどいです。(わかってるなら直せ)

  • 環境
    • google colab

常にこのサイトを開きながら作業してました。ありがたいです
* 基本的な正規表現一覧
* サルにもわかる正規表現入門

目次

第3章: 正規表現

21. カテゴリ名を含む行を抽出
22. カテゴリ名の抽出
23. セクション構造
24. ファイル参照の抽出
25. テンプレートの抽出
26. 強調マークアップの除去
27. 内部リンクの除去
28. MediaWikiマークアップの除去
29. 国旗画像のURLを取得する

20. JSONデータの読み込み

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

コメント

jsonファイルのデータが,で区切られいないかエラーが発生してるようです。詳しくは@ITNewcomerさんの〜言語処理100本ノック No.20〜で詳しく書かれています。

with open('jawiki-country.json','r')as json_source:
  country = json.load(json_source)
エラー文
JSONDecodeError: Extra data: line 2 column 1 (char 38123)
import json
with open('jawiki-country.json','r')as json_source:
  for i in json_source:
    country = json.loads(i)
    if 'イギリス' == country['title']:
      eng = country
      break
eng変数の中身
{'title': 'イギリス', 'text': '{{redirect|UK}}\n{{redirect|英国|春秋時代の諸侯 ・・・}

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

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

失敗例
eng_content = eng['text'].split('\n')
category = []
for i in eng_content:
  if i.find('Category') >= 0:
    category.append(i)

# category[0]が不要, 正規表現でもっと狭い範囲を指定する必要あり
['{{Sisterlinks|commons=United Kingdom|commonscat=United Kingdom|s=Category:イギリス|n=Category:イギリス|voy=United Kingdom}}', '[[Category:イギリス|*]]', '[[Category:イギリス連邦加盟国]]', '[[Category:英連邦王国|*]]', '[[Category:G8加盟国]]', '[[Category:欧州連合加盟国|元]]', '[[Category:海洋国家]]', '[[Category:現存する君主国]]', '[[Category:島国]]', '[[Category:1801年に成立した国家・領域]]']

取り出したい部分はこうなっている

[[Category:イギリス|*]]
[[Category:イギリス連邦加盟国]]
[[Category:英連邦王国|*]]
[[Category:G8加盟国]]
[[Category:欧州連合加盟国|元]]
[[Category:海洋国家]]
[[Category:現存する君主国]]
[[Category:島国]]
[[Category:1801年に成立した国家・領域]]
解答
import re
eng_content = eng['text'].split('\n')
category = []
for i in eng_content:
  if re.match(r"\[\[Category\:",str(i)):
    category.append(i)
出力
['[[Category:イギリス|*]]', '[[Category:イギリス連邦加盟国]]', '[[Category:英連邦王国|*]]', '[[Category:G8加盟国]]', '[[Category:欧州連合加盟国|元]]', '[[Category:海洋国家]]', '[[Category:現存する君主国]]', '[[Category:島国]]', '[[Category:1801年に成立した国家・領域]]']

22. カテゴリ名の抽出

記事のカテゴリ名を(行単位ではなく名前で)抽出せよ.

コメント

|を使ったら文末とかでも処理できる

processed_category = []
for i in category:
  print(type(i))
  processed_category.append(re.sub(r"\[\[Category\:|\]\]|\|\*\]\]","",i))

print(processed_category)
['イギリス', 'イギリス連邦加盟国', '英連邦王国', 'G8加盟国', '欧州連合加盟国|元', '海洋国家', '現存する君主国', '島国', '1801年に成立した国家・領域']

23. セクション構造

記事中に含まれるセクション名とそのレベル(例えば”== セクション名 ==”なら1)を表示せよ.

コメント

def pro_section(row):は再起とか使ったら自動化できそう

def pro_section(row):
  pro = re.sub(r"^\=|\=$",'',row)
  print(pro)
  if re.match(r"^\=|\=$",pro):
    pro = re.sub(r"^\=|\=$",'',pro)
    if re.match(r"^\=|\=$",pro):
      pro = re.sub(r"^\=|\=$",'',pro)
      return pro,3
    return pro,2
  return pro,1

dic_section ={}
for i in eng_content:
  if re.match(r"^\=\=|\=\=$",i):
    print(i)
    section,n=pro_section(i)
    dic_section[section] = n

print(dic_section)
{'国名': 2, '歴史': 2, '地理': 2, '主要都市': 3, '気候': 3, '政治': 2, '元首': 3, '法': 3, '内政': 3, '地方行政区分': 3, '外交・軍事': 3, '経済': 2, '鉱業': 3, '農業': 3, '貿易': 3, '不動産': 3, 'エネルギー政策': 3, '通貨': 3, '企業': 3, '=通信=': 3, '交通': 2, '道路': 3, '鉄道': 3, '海運': 3, '航空': 3, '科学技術': 2, '国民': 2, '言語': 3, '宗教': 3, '婚姻': 3, '移住': 3, '教育': 3, '医療': 3, '文化': 2, '食文化': 3, '文学': 3, '哲学': 3, '音楽': 3, '=ポピュラー音楽=': 3, '映画': 3, 'コメディ': 3, '国花': 3, '世界遺産': 3, '祝祭日': 3, 'スポーツ': 3, '=サッカー=': 3, '=クリケット=': 3, '=競馬=': 3, '=モータースポーツ=': 3, '=野球=': 3, '= カーリング =': 3, '= 自転車競技 =': 3, '脚注': 2, '関連項目': 2, '外部リンク': 2}

24. ファイル参照の抽出

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

コメント

かなり時間かかった

a =''
for i in eng_content:
  if re.search(r"\[\[ファイル:",i):
    a=re.findall(r"\[\[ファイル:([^|]+?)\|.*?\]\]",i)
    for j in a:
      print(j)

25. テンプレートの抽出

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

コメント

「基礎情報」テンプレートがどこなのかわからなかったので他の方の解答見て大体どこか把握しました。どうやら|から始まるところっぽいです。

import re
b=''
for i in eng_content:
  if re.match(r'^\|[^\=]+\s=',i):
    b = re.findall(r'^\|([^=]*?)\s*=\s*(\[*?.*\]*?)',i)
    print(b)
出力(一部)
[('略名', 'イギリス')]
[('日本語国名', 'グレートブリテン及び北アイルランド連合王国')]
[('公式国名', '{{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:<br />')]
[('国旗画像', 'Flag of the United Kingdom.svg')]
[('国章画像', '[[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]]')]
[('国章リンク', '([[イギリスの国章|国章]])')]

出力全文
[('略名', 'イギリス')]
[('日本語国名', 'グレートブリテン及び北アイルランド連合王国')]
[('公式国名', '{{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:<br />')]
[('国旗画像', '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')]
[('公用語', '[[英語]]')]
[('首都', '[[ロンドン]](事実上)')]
[('最大都市', 'ロンドン')]
[('元首等肩書', '[[イギリスの君主|女王]]')]
[('元首等氏名', '[[エリザベス2世]]')]
[('首相等肩書', '[[イギリスの首相|首相]]')]
[('首相等氏名', '[[ボリス・ジョンソン]]')]
[('他元首等肩書1', '[[貴族院 (イギリス)|貴族院議長]]')]
[('他元首等氏名1', '[[:en:Norman Fowler, Baron Fowler|ノーマン・ファウラー]]')]
[('他元首等肩書2', '[[庶民院 (イギリス)|庶民院議長]]')]
[('他元首等氏名2', '{{仮リンク|リンゼイ・ホイル|en|Lindsay Hoyle}}')]
[('他元首等肩書3', '[[連合王国最高裁判所|最高裁判所長官]]')]
[('他元首等氏名3', '[[:en:Brenda Hale, Baroness Hale of Richmond|ブレンダ・ヘイル]]')]
[('面積順位', '76')]
[('面積大きさ', '1 E11')]
[('面積値', '244,820')]
[('水面積率', '1.3%')]
[('人口統計年', '2018')]
[('人口順位', '22')]
[('人口大きさ', '1 E7')]
[('人口値', '6643万5600<ref>{{Cite web|url=https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationestimates|title=Population estimates - Office for National Statistics|accessdate=2019-06-26|date=2019-06-26}}</ref>')]
[('人口密度値', '271')]
[('GDP統計年元', '2012')]
[('GDP値元', '1兆5478億<ref name="imf-statistics-gdp">[http://www.imf.org/external/pubs/ft/weo/2012/02/weodata/weorept.aspx?pr.x=70&pr.y=13&sy=2010&ey=2012&scsm=1&ssd=1&sort=country&ds=.&br=1&c=112&s=NGDP%2CNGDPD%2CPPPGDP%2CPPPPC&grp=0&a=IMF>Data and Statistics>World Economic Outlook Databases>By Countrise>United Kingdom]</ref>')]
[('GDP統計年MER', '2012')]
[('GDP順位MER', '6')]
[('GDP値MER', '2兆4337億<ref name="imf-statistics-gdp" />')]
[('GDP統計年', '2012')]
[('GDP順位', '6')]
[('GDP値', '2兆3162億<ref name="imf-statistics-gdp" />')]
[('GDP/人', '36,727<ref name="imf-statistics-gdp" />')]
[('建国形態', '建国')]
[('確立形態1', '[[イングランド王国]]/[[スコットランド王国]]<br />(両国とも[[合同法 (1707年)|1707年合同法]]まで)')]
[('確立年月日1', '927年/843年')]
[('確立形態2', '[[グレートブリテン王国]]成立<br />(1707年合同法)')]
[('確立年月日2', '1707年{{0}}5月{{0}}1日')]
[('確立形態3', '[[グレートブリテン及びアイルランド連合王国]]成立<br />([[合同法 (1800年)|1800年合同法]])')]
[('確立年月日3', '1801年{{0}}1月{{0}}1日')]
[('確立形態4', "現在の国号「'''グレートブリテン及び北アイルランド連合王国'''」に変更")]
[('確立年月日4', '1927年{{0}}4月12日')]
[('通貨', '[[スターリング・ポンド|UKポンド]] (£)')]
[('通貨コード', 'GBP')]
[('時間帯', '±0')]
[('夏時間', '+1')]
[('ISO 3166-1', 'GB / GBR')]
[('ccTLD', '[[.uk]] / [[.gb]]<ref>使用は.ukに比べ圧倒的少数。</ref>')]
[('国際電話番号', '44')]
[('注記', '<references/>')]

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

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

コメント

findall()で取り出したものはlist型の中にtuple型のデータが入ってるからそれの処理が必要

import re

def delete_enhance(data):
  pro=re.sub("'+",'',data)
  return pro

li=[]
#25のコードを加工''
for i in eng_content:
  if re.match(r'^\|[^\=]+\s=',i):
    b = re.findall(r'^\|([^=]*?)\s*=\s*(\[*?.*\]*?)',i)
    d[b[0][0]] = delete_enhance(b[0][1])
print(d)
出力
{'略名': 'イギリス', '日本語国名': 'グレートブリテン及び北アイルランド連合王国', '公式国名': '{{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:<br />', '国旗画像': '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', '公用語': '[[英語]]', '首都': '[[ロンドン]](事実上)', '最大都市': 'ロンドン', '元首等肩書': '[[イギリスの君主|女王]]', '元首等氏名': '[[エリザベス2世]]', '首相等肩書': '[[イギリスの首相|首相]]', '首相等氏名': '[[ボリス・ジョンソン]]', '他元首等肩書1': '[[貴族院 (イギリス)|貴族院議長]]', '他元首等氏名1': '[[:en:Norman Fowler, Baron Fowler|ノーマン・ファウラー]]', '他元首等肩書2': '[[庶民院 (イギリス)|庶民院議長]]', '他元首等氏名2': '{{仮リンク|リンゼイ・ホイル|en|Lindsay Hoyle}}', '他元首等肩書3': '[[連合王国最高裁判所|最高裁判所長官]]', '他元首等氏名3': '[[:en:Brenda Hale, Baroness Hale of Richmond|ブレンダ・ヘイル]]', '面積順位': '76', '面積大きさ': '1 E11', '面積値': '244,820', '水面積率': '1.3%', '人口統計年': '2018', '人口順位': '22', '人口大きさ': '1 E7', '人口値': '6643万5600<ref>{{Cite web|url=https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationestimates|title=Population estimates - Office for National Statistics|accessdate=2019-06-26|date=2019-06-26}}</ref>', '人口密度値': '271', 'GDP統計年元': '2012', 'GDP値元': '1兆5478億<ref name="imf-statistics-gdp">[http://www.imf.org/external/pubs/ft/weo/2012/02/weodata/weorept.aspx?pr.x=70&pr.y=13&sy=2010&ey=2012&scsm=1&ssd=1&sort=country&ds=.&br=1&c=112&s=NGDP%2CNGDPD%2CPPPGDP%2CPPPPC&grp=0&a=IMF>Data and Statistics>World Economic Outlook Databases>By Countrise>United Kingdom]</ref>', 'GDP統計年MER': '2012', 'GDP順位MER': '6', 'GDP値MER': '2兆4337億<ref name="imf-statistics-gdp" />', 'GDP統計年': '2012', 'GDP順位': '6', 'GDP値': '2兆3162億<ref name="imf-statistics-gdp" />', 'GDP/人': '36,727<ref name="imf-statistics-gdp" />', '建国形態': '建国', '確立形態1': '[[イングランド王国]]/[[スコットランド王国]]<br />(両国とも[[合同法 (1707年)|1707年合同法]]まで)', '確立年月日1': '927年/843年', '確立形態2': '[[グレートブリテン王国]]成立<br />(1707年合同法)', '確立年月日2': '1707年{{0}}5月{{0}}1日', '確立形態3': '[[グレートブリテン及びアイルランド連合王国]]成立<br />([[合同法 (1800年)|1800年合同法]])', '確立年月日3': '1801年{{0}}1月{{0}}1日', '確立形態4': '現在の国号「グレートブリテン及び北アイルランド連合王国」に変更', '確立年月日4': '1927年{{0}}4月12日', '通貨': '[[スターリング・ポンド|UKポンド]] (£)', '通貨コード': 'GBP', '時間帯': '±0', '夏時間': '+1', 'ISO 3166-1': 'GB / GBR', 'ccTLD': '[[.uk]] / [[.gb]]<ref>使用は.ukに比べ圧倒的少数。</ref>', '国際電話番号': '44', '注記': '<references/>'}

27. 内部リンクの除去

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

コメント

マークアップ早見表の内部リンクには


#26の辞書変数dを使う
import re

def delete_inner_link(data):
  pro=re.sub('\[\[|\]\]','',data)
  return pro

for key,value in d.items():
  d[key] = delete_inner_link(value)
print(d)

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

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

#28のdを使う
def pro_data(data):
  #<ref>関連削除
  a = re.sub('(\<ref[^>]*\>)(.*)(\<\/ref\>)??','',data)
  #<br />削除
  b = re.sub('\<br\s\/\>','',a)
  #{{}}削除
  c = re.sub('\{\{|\}\}','',b)
  #消し忘れてた 言語タグ?みたいなやつ削除 lang|en|
  d = re.sub('lang\|[a-z]{2}\|','',c)
  #前の課題で消せなかった 言語間リンク削除
  e = re.sub('\:[a-z]{2}\:','',d)
  return e

for i,j in d.items():
  d[i] = pro_data(j)
出力(一部)
略名 : イギリス
日本語国名 : グレートブリテン及び北アイルランド連合王国
公式国名 : United Kingdom of Great Britain and Northern Ireland
国旗画像 : Flag of the United Kingdom.svg
国章画像 : ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章
国章リンク : (イギリスの国章|国章)
標語 : Dieu et mon droit(フランス語:Dieu et mon droit|神と我が権利)
国歌 : 女王陛下万歳|God Save the Queenen icon神よ女王を護り賜えcenter|ファイル:United States Navy Band - God Save the Queen.ogg
地図画像 : Europe-UK.svg
位置画像 : United Kingdom (+overseas territories) in the World (+Antarctica claims).svg
公用語 : 英語


出力全文
略名 : イギリス
日本語国名 : グレートブリテン及び北アイルランド連合王国
公式国名 : United Kingdom of Great Britain and Northern Ireland
国旗画像 : Flag of the United Kingdom.svg
国章画像 : ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章
国章リンク : (イギリスの国章|国章)
標語 : Dieu et mon droit(フランス語:Dieu et mon droit|神と我が権利)
国歌 : 女王陛下万歳|God Save the Queenen icon神よ女王を護り賜えcenter|ファイル:United States Navy Band - God Save the Queen.ogg
地図画像 : Europe-UK.svg
位置画像 : United Kingdom (+overseas territories) in the World (+Antarctica claims).svg
公用語 : 英語
首都 : ロンドン(事実上)
最大都市 : ロンドン
元首等肩書 : イギリスの君主|女王
元首等氏名 : エリザベス2世
首相等肩書 : イギリスの首相|首相
首相等氏名 : ボリス・ジョンソン
他元首等肩書1 : 貴族院 (イギリス)|貴族院議長
他元首等氏名1 : Norman Fowler, Baron Fowler|ノーマン・ファウラー
他元首等肩書2 : 庶民院 (イギリス)|庶民院議長
他元首等氏名2 : 仮リンク|リンゼイ・ホイル|en|Lindsay Hoyle
他元首等肩書3 : 連合王国最高裁判所|最高裁判所長官
他元首等氏名3 : Brenda Hale, Baroness Hale of Richmond|ブレンダ・ヘイル
面積順位 : 76
面積大きさ : 1 E11
面積値 : 244,820
水面積率 : 1.3%
人口統計年 : 2018
人口順位 : 22
人口大きさ : 1 E7
人口値 : 6643万5600
人口密度値 : 271
GDP統計年元 : 2012
GDP値元 : 1兆5478億
GDP統計年MER : 2012
GDP順位MER : 6
GDP値MER : 2兆4337億
GDP統計年 : 2012
GDP順位 : 6
GDP値 : 2兆3162億
GDP/人 : 36,727
建国形態 : 建国
確立形態1 : イングランド王国/スコットランド王国(両国とも合同法 (1707年)|1707年合同法まで)
確立年月日1 : 927年/843年
確立形態2 : グレートブリテン王国成立(1707年合同法)
確立年月日2 : 1707年05月01日
確立形態3 : グレートブリテン及びアイルランド連合王国成立(合同法 (1800年)|1800年合同法)
確立年月日3 : 1801年01月01日
確立形態4 : 現在の国号「グレートブリテン及び北アイルランド連合王国」に変更
確立年月日4 : 1927年04月12日
通貨 : スターリング・ポンド|UKポンド (£)
通貨コード : GBP
時間帯 : ±0
夏時間 : +1
ISO 3166-1 : GB / GBR
ccTLD : .uk / .gb
国際電話番号 : 44
注記 :

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

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

コメント

さっぱりわからん

感想

正規表現終盤の方になってくると慣れてきて早く書けるようになりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0