0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

言語処理100本ノック-26:強調マークアップの除去

Posted at

言語処理100本ノック 2015「第3章: 正規表現」26本目「強調マークアップの除去」記録です。
今回から28本目までは正規表現でマークアップ除去をしていきます。今回は**sub関数を使った除去(置換)**を学びます。

参考リンク

リンク 備考
026.強調マークアップの除去.ipynb 回答プログラムのGitHubリンク
素人の言語処理100本ノック:26 多くのソース部分のコピペ元
ゼロから覚える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で圧縮される

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

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

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

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

Help:早見表によると「強調マークアップ」は以下の3種類です。

種類 書式
他との区別(斜体) シングルクォート2つで囲む ''他との区別''
強調(太字) シングルクォート3つで囲む '''強調'''
斜体と強調 シングルクォート5つで囲む '''''斜体と強調'''''

ファイル内の以下の部分を正規表現で抽出します。今回の対象には「強調(太字)」しかないようです。

ファイル内の「強調マークアップ」部分抜粋
"|確立形態4 = 現在の国号「'''グレートブリテン及び北アイルランド連合王国'''」に変更\n

回答

回答プログラム 026.強調マークアップの除去.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)
    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)

回答解説

今回のメインは以下の部分です。sub関数を使って「強調マークアップ」の除去(置換)をしています。4つ目の引数にcountがあるのでflags(コンパイルフラグ)を渡すときには名前を明示する必要があります。countに気づかずに必死でコンパイルフラグを渡した気になっていて、うまく行かずに30分ほど無駄にしました・・・

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

sub関数は文字置換をします。引数の順に1. 正規表現パターン、2. 置換後の文字列、3. 置換対象文字列です。

>>> re.sub(r'置換対象', '置換済', '置換対象 対象外 置換対象')
'置換済 対象外 置換済'

ちなみに「確立形態4」の値が変更前と後で以下のようになります。

41 確立形態4
変更前	 現在の国号「'''グレートブリテン及び北アイルランド連合王国'''」に変更
変更後	 現在の国号「グレートブリテン及び北アイルランド連合王国」に変更
----

出力結果(実行結果)

プログラム実行すると以下の結果が出力されます。まだ残っているマークアップは27、28本目で除去します。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?