LoginSignup
1
1

More than 3 years have passed since last update.

言語処理100本ノック-28:MediaWikiマークアップの除去

Posted at

言語処理100本ノック 2015「第3章: 正規表現」28本目「MediaWikiマークアップの除去」記録です。今回でマークアップ除去系は終わりです。新しく覚える内容はなく、今まで習ったことを実践で使うノックです。

参考リンク

リンク 備考
028.MediaWikiマークアップの除去.ipynb 回答プログラムのGitHubリンク
素人の言語処理100本ノック:28 多くのソース部分のコピペ元
ゼロから覚えるPython正規表現の基本とTips 当ノックで学習した内容を整理しました
正規表現 HOWTO Python公式の正規表現How To
re --- 正規表現操作 Python公式のreパッケージ説明
Help:早見表 Wikipediaの代表的なマークアップの早見表

環境

種類 バージョン 内容
OS Ubuntu18.04.01 LTS 仮想で動かしています
pyenv 1.2.15 複数Python環境を使うことがあるのでpyenv使っています
Python 3.6.9 pyenv上でpython3.6.9を使っています
3.7や3.8系を使っていないことに深い理由はありません
パッケージはvenvを使って管理しています

上記環境で、以下のPython追加パッケージを使っています。通常のpipでインストールするだけです。

種類 バージョン
pandas 0.25.3

第3章: 正規表現

学習内容

Wikipediaのページのマークアップ記述に正規表現を適用することで,様々な情報・知識を取り出します.

正規表現, JSON, Wikipedia, InfoBox, ウェブサービス

ノック内容

Wikipediaの記事を以下のフォーマットで書き出したファイルjawiki-country.json.gzがある.

  • 1行に1記事の情報がJSON形式で格納される
  • 各行には記事名が"title"キーに,記事本文が"text"キーの辞書オブジェクトに格納され,そのオブジェクトがJSON形式で書き出される
  • ファイル全体はgzipで圧縮される

以下の処理を行うプログラムを作成せよ.

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

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

課題補足(「MediaWikiマークアップ」について)

「MediaWikiマークアップを可能な限り」ですか・・・
ファイル内の以下の部分を正規表現で抽出しています。

種類 書式 参照元
ファイル [[ファイル:Wikipedia-logo-v2-ja.png|thumb|説明文]] Help:早見表
外部リンク [http://www.example.org]
[http://www.example.org 表示文字]
Help:早見表
Template:Lang {{lang|言語タグ|文字列}} Template:Lang
HTMLタグ <tag> なし

回答

回答プログラム 028.MediaWikiマークアップの除去.ipynb

from collections import OrderedDict
from pprint import pprint
import re

import pandas as pd

def extract_by_title(title):
    df_wiki = pd.read_json('jawiki-country.json', lines=True)
    return df_wiki[(df_wiki['title'] == title)]['text'].values[0]

wiki_body = extract_by_title('イギリス')

basic = re.search(r'''
                    ^\{\{基礎情報.*?\n  #検索語句(\はエスケープ処理)、非キャプチャ、非貪欲
                    (.*?)              #任意の文字列
                    \}\}               #検索語句(\はエスケープ処理)
                    $                  #文字列の末尾
                    ''', wiki_body, re.MULTILINE+re.VERBOSE+re.DOTALL)

templates = OrderedDict(re.findall(r'''
                          ^\|         # \はエスケープ処理、非キャプチャ
                          (.+?)       # キャプチャ対象(key)、非貪欲
                          \s*         # 空白文字0文字以上
                          =           # 検索語句、非キャプチャ
                          \s*         # 空白文字0文字以上
                          (.+?)       # キャプチャ対象(Value)、非貪欲
                          (?:         # キャプチャ対象外のグループ開始
                            (?=\n\|)  # 改行(\n)+'|'の手前(肯定の先読み)
                          | (?=\n$)   # または、改行(\n)+終端の手前(肯定の先読み)
                          )           # キャプチャ対象外のグループ終了
                         ''', basic.group(1), re.MULTILINE+re.VERBOSE+re.DOTALL))

# マークアップ除去
def remove_markup(string):

    # 強調マークアップの除去 
    # 除去対象:''他との区別''、'''強調'''、'''''斜体と強調'''''
    replaced = re.sub(r'''
                       (\'{2,5})   # 2〜5個の'(マークアップの開始)
                       (.*?)       # 任意の1文字以上(対象の文字列)
                       (\1)        # 1番目のキャプチャと同じ(マークアップの終了)
                       ''', r'\2', string, flags=re.MULTILINE+re.VERBOSE)

    # 内部リンク・ファイルの除去 
    # 除去対象:[[記事名]]、[[記事名|表示文字]]、[[記事名#節名|表示文字]]、[[ファイル:Wi.png|thumb|説明文]]
    replaced = re.sub(r'''
        \[\[             # '[['(マークアップ開始)
        (?:              # キャプチャ対象外のグループ開始
            [^|]*?       # '|'以外の文字0文字以上、非貪欲
            \|           # '|'
        )*?              # グループ終了、このグループが0以上出現、非貪欲(No27との変更点)
        (                # グループ開始、キャプチャ対象
          (?!Category:)  # 否定の先読(含んだ場合は対象外としている)
          ([^|]*?)    # '|'以外が0文字以上、非貪欲(表示対象の文字列)
        )
        \]\]        # ']]'(マークアップ終了)        
        ''', r'\1', replaced, flags=re.MULTILINE+re.VERBOSE)

    # Template:Langの除去 
    # 除去対象:{{lang|言語タグ|文字列}}
    replaced = re.sub(r'''
        \{\{lang    # '{{lang'(マークアップ開始)
        (?:         # キャプチャ対象外のグループ開始
            [^|]*?  # '|'以外の文字が0文字以上、非貪欲
            \|      # '|'
        )*?         # グループ終了、このグループが0以上出現、非貪欲
        ([^|]*?)    # キャプチャ対象、'|'以外が0文字以上、非貪欲(表示対象の文字列)
        \}\}        # '}}'(マークアップ終了)
        ''', r'\1', replaced, flags=re.MULTILINE+re.VERBOSE)

    # 外部リンクの除去
    # 除去対象[http(s)://xxxx] 、[http(s)://xxx xxx]
    replaced = re.sub(r'''
        \[https?:// # '[http://'(マークアップ開始)
        (?:           # キャプチャ対象外のグループ開始
            [^\s]*? # 空白以外の文字が0文字以上、非貪欲
            \s      # 空白
        )?          # グループ終了、このグループが0か1出現
        ([^]]*?)    # キャプチャ対象、']'以外が0文字以上、非貪欲(表示対象の文字列)
        \]          # ']'(マークアップの終了)
        ''', r'\1', replaced, flags=re.MULTILINE+re.VERBOSE)

    # HTMLタグの除去
    # 除去対象 <xx> </xx> <xx/>
    replaced = re.sub(r'''
        <           # '<'(マークアップの開始)
        .+?         # 1文字以上、非貪欲
        >           # '>'(マークアップの終了)
        ''', '', replaced, flags=re.MULTILINE+re.VERBOSE)

    return replaced

for i, (key, value) in enumerate(templates.items()):
    replaced = remove_markup(value)
    templates[key] = replaced

    # 変わったものを表示
    if value != replaced:
        print(i, key) 
        print('変更前\t', value)
        print('変更後\t', replaced)
        print('----')

pprint(templates)

回答解説

「ファイル」除去

前回ノックの「内部リンク」除去とほぼ同じなので、該当部分正規表現に修正をしています。
具体的には下記の1つ目のグループの終わりを)??から)*?へと変更しています。ファイルの場合は[[ファイル:Wikipedia-logo-v2-ja.png|thumb|説明文]]|が2回以上登場するので、0回以上にしています。

replaced = re.sub(r'''
    \[\[             # '[['(マークアップ開始)
    (?:              # キャプチャ対象外のグループ開始
        [^|]*?       # '|'以外の文字0文字以上、非貪欲
        \|           # '|'
    )*?              # グループ終了、このグループが0以上出現、非貪欲(No27との変更点)
    (                # グループ開始、キャプチャ対象
      (?!Category:)  # 否定の先読(含んだ場合は対象外としている)
      ([^|]*?)    # '|'以外が0文字以上、非貪欲(表示対象の文字列)
    )
    \]\]        # ']]'(マークアップ終了)        
    ''', r'\1', replaced, flags=re.MULTILINE+re.VERBOSE)

以下がファイル除去の変更前と変更後です。

4 国章画像
変更前    [[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]]
変更後    イギリスの国章

「Template:Lang」除去

{{lang|言語タグ|文字列}}形式を「文字列」のみに置換しています。

# 除去対象:{{lang|言語タグ|文字列}}
replaced = re.sub(r'''
    \{\{lang    # '{{lang'(マークアップ開始)
    (?:         # キャプチャ対象外のグループ開始
        [^|]*?  # '|'以外の文字が0文字以上、非貪欲
        \|      # '|'
    )*?         # グループ終了、このグループが0以上出現、非貪欲
    ([^|]*?)    # キャプチャ対象、'|'以外が0文字以上、非貪欲(表示対象の文字列)
    \}\}        # '}}'(マークアップ終了)
    ''', r'\1', replaced, flags=re.MULTILINE+re.VERBOSE)

以下が「Template:Lang」除去結果です。

2 公式国名
変更前    {{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:<br/>
*{{lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath}}([[スコットランド・ゲール語]])<br/>
*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon}}([[ウェールズ語]])<br/>
*{{lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann}}([[アイルランド語]])<br/>
*{{lang|kw|An Rywvaneth Unys a Vreten Veur hag Iwerdhon Glédh}}([[コーンウォール語]])<br/>
*{{lang|sco|Unitit Kinrick o Great Breetain an Northren Ireland}}([[スコットランド語]])<br/>
**{{lang|sco|Claught Kängrick o Docht Brätain an Norlin Airlann}}、{{lang|sco|Unitet Kängdom o Great Brittain an Norlin Airlann}}(アルスター・スコットランド語)</ref>
変更後    United Kingdom of Great Britain and Northern Ireland英語以外での正式国名:
*An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath(スコットランド・ゲール語)
*Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon(ウェールズ語)
*Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann(アイルランド語)
*An Rywvaneth Unys a Vreten Veur hag Iwerdhon Glédh(コーンウォール語)
*Unitit Kinrick o Great Breetain an Northren Ireland(スコットランド語)
**Claught Kängrick o Docht Brätain an Norlin Airlann、Unitet Kängdom o Great Brittain an Norlin Airlann(アルスター・スコットランド語)
----
6 標語
変更前    {{lang|fr|Dieu et mon droit}}<br/>([[フランス語]]:神と私の権利)
変更後    Dieu et mon droit(フランス語:神と私の権利)

「外部リンク」除去

httpsも含めて除去しています。

# 除去対象[http(s)://xxxx] 、[http(s)://xxx xxx]
replaced = re.sub(r'''
    \[https?:// # '[http://'(マークアップ開始)
    (?:           # キャプチャ対象外のグループ開始
        [^\s]*? # 空白以外の文字が0文字以上、非貪欲
        \s      # 空白
    )?          # グループ終了、このグループが0か1出現
    ([^]]*?)    # キャプチャ対象、']'以外が0文字以上、非貪欲(表示対象の文字列)
    \]          # ']'(マークアップの終了)
    ''', r'\1', replaced, flags=re.MULTILINE+re.VERBOSE)

以下が外部リンク除去部分です。

23 人口値
変更前    63,181,775<ref>[http://esa.un.org/unpd/wpp/Excel-Data/population.htm United Nations Department of Economic and Social Affairs>Population Division>Data>Population>Total Population]</ref>
変更後    63,181,775United Nations Department of Economic and Social Affairs>Population Division>Data>Population>Total Population
----
26 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>
変更後    1兆5478億IMF>Data and Statistics>World Economic Outlook Databases>By Countrise>United Kingdom

「HTMLタグ」除去

HTMLタグも除去しています。「<>に囲まれていたら」という単純な正規表現。

# 除去対象 <xx> </xx> <xx/>
replaced = re.sub(r'''
    <           # '<'(マークアップの開始)
    .+?         # 1文字以上、非貪欲
    >           # '>'(マークアップの終了)
    ''', '', replaced, flags=re.MULTILINE+re.VERBOSE)

以下が結果です。結構多いですね。

2 公式国名
変更前    {{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:<br/>
*{{lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath}}([[スコットランド・ゲール語]])<br/>
*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon}}([[ウェールズ語]])<br/>
*{{lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann}}([[アイルランド語]])<br/>
*{{lang|kw|An Rywvaneth Unys a Vreten Veur hag Iwerdhon Glédh}}([[コーンウォール語]])<br/>
*{{lang|sco|Unitit Kinrick o Great Breetain an Northren Ireland}}([[スコットランド語]])<br/>
**{{lang|sco|Claught Kängrick o Docht Brätain an Norlin Airlann}}、{{lang|sco|Unitet Kängdom o Great Brittain an Norlin Airlann}}(アルスター・スコットランド語)</ref>
変更後    United Kingdom of Great Britain and Northern Ireland英語以外での正式国名:
*An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath(スコットランド・ゲール語)
*Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon(ウェールズ語)
*Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann(アイルランド語)
*An Rywvaneth Unys a Vreten Veur hag Iwerdhon Glédh(コーンウォール語)
*Unitit Kinrick o Great Breetain an Northren Ireland(スコットランド語)
**Claught Kängrick o Docht Brätain an Norlin Airlann、Unitet Kängdom o Great Brittain an Norlin Airlann(アルスター・スコットランド語)
----
6 標語
変更前    {{lang|fr|Dieu et mon droit}}<br/>([[フランス語]]:神と私の権利)
変更後    Dieu et mon droit(フランス語:神と私の権利)
----
23 人口値
変更前    63,181,775<ref>[http://esa.un.org/unpd/wpp/Excel-Data/population.htm United Nations Department of Economic and Social Affairs>Population Division>Data>Population>Total Population]</ref>
変更後    63,181,775United Nations Department of Economic and Social Affairs>Population Division>Data>Population>Total Population
----
26 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>
変更後    1兆5478億IMF>Data and Statistics>World Economic Outlook Databases>By Countrise>United Kingdom
----
29 GDP値MER
変更前    2兆4337億<ref name="imf-statistics-gdp" />
変更後    2兆4337億
----
32 GDP値
変更前    2兆3162億<ref name="imf-statistics-gdp" />
変更後    2兆3162億
----
33 GDP/人
変更前    36,727<ref name="imf-statistics-gdp" />
変更後    36,727
----
37 確立形態2
変更前    [[グレートブリテン王国]]建国<br />([[連合法 (1707年)|1707年連合法]])
変更後    グレートブリテン王国建国(1707年連合法)
----
39 確立形態3
変更前    [[グレートブリテン及びアイルランド連合王国]]建国<br />([[連合法 (1800年)|1800年連合法]])
変更後    グレートブリテン及びアイルランド連合王国建国(1800年連合法)
----
48 ccTLD
変更前    [[.uk]] / [[.gb]]<ref>使用は.ukに比べ圧倒的少数。</ref>
変更後    .uk / .gb使用は.ukに比べ圧倒的少数。
----
50 注記
変更前    <references />
変更後    

出力結果(実行結果)

プログラム実行すると最後に以下の結果が出力されます。すっきりしました。

出力結果
OrderedDict([('略名', 'イギリス'),
             ('日本語国名', 'グレートブリテン及び北アイルランド連合王国'),
             ('公式国名',
              'United Kingdom of Great Britain and Northern '
              'Ireland英語以外での正式国名:\n'
              '*An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu '
              'Thuath(スコットランド・ゲール語)\n'
              '*Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon(ウェールズ語)\n'
              '*Ríocht Aontaithe na Breataine Móire agus Tuaisceart na '
              'hÉireann(アイルランド語)\n'
              '*An Rywvaneth Unys a Vreten Veur hag Iwerdhon Glédh(コーンウォール語)\n'
              '*Unitit Kinrick o Great Breetain an Northren Ireland(スコットランド語)\n'
              '**Claught Kängrick o Docht Brätain an Norlin Airlann、Unitet '
              'Kängdom o Great Brittain an Norlin Airlann(アルスター・スコットランド語)'),
             ('国旗画像', 'Flag of the United Kingdom.svg'),
             ('国章画像', 'イギリスの国章'),
             ('国章リンク', '(国章)'),
             ('標語', 'Dieu et mon droit(フランス語:神と私の権利)'),
             ('国歌', '神よ女王陛下を守り給え'),
             ('位置画像', 'Location_UK_EU_Europe_001.svg'),
             ('公用語', '英語(事実上)'),
             ('首都', 'ロンドン'),
             ('最大都市', 'ロンドン'),
             ('元首等肩書', '女王'),
             ('元首等氏名', 'エリザベス2世'),
             ('首相等肩書', '首相'),
             ('首相等氏名', 'デーヴィッド・キャメロン'),
             ('面積順位', '76'),
             ('面積大きさ', '1 E11'),
             ('面積値', '244,820'),
             ('水面積率', '1.3%'),
             ('人口統計年', '2011'),
             ('人口順位', '22'),
             ('人口大きさ', '1 E7'),
             ('人口値',
              '63,181,775United Nations Department of Economic and Social '
              'Affairs>Population Division>Data>Population>Total Population'),
             ('人口密度値', '246'),
             ('GDP統計年元', '2012'),
             ('GDP値元',
              '1兆5478億IMF>Data and Statistics>World Economic Outlook '
              'Databases>By Countrise>United Kingdom'),
             ('GDP統計年MER', '2012'),
             ('GDP順位MER', '5'),
             ('GDP値MER', '2兆4337億'),
             ('GDP統計年', '2012'),
             ('GDP順位', '6'),
             ('GDP値', '2兆3162億'),
             ('GDP/人', '36,727'),
             ('建国形態', '建国'),
             ('確立形態1', 'イングランド王国/スコットランド王国(両国とも1707年連合法まで)'),
             ('確立年月日1', '927年/843年'),
             ('確立形態2', 'グレートブリテン王国建国(1707年連合法)'),
             ('確立年月日2', '1707年'),
             ('確立形態3', 'グレートブリテン及びアイルランド連合王国建国(1800年連合法)'),
             ('確立年月日3', '1801年'),
             ('確立形態4', '現在の国号「グレートブリテン及び北アイルランド連合王国」に変更'),
             ('確立年月日4', '1927年'),
             ('通貨', 'UKポンド (&pound;)'),
             ('通貨コード', 'GBP'),
             ('時間帯', '±0'),
             ('夏時間', '+1'),
             ('ISO 3166-1', 'GB / GBR'),
             ('ccTLD', '.uk / .gb使用は.ukに比べ圧倒的少数。'),
             ('国際電話番号', '44'),
             ('注記', '')])
1
1
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
1
1