言語処理100本ノック-24:ファイル参照の抽出

[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)[「第3章: 正規表現」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch3)の[24本目「ファイル参照の抽出」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#sec24)記録です。今回学習するのは**和集合(or)**です。「和集合(or)」は非常に簡単でわかりやすいです。

# 参考リンク

|リンク|備考|
|:--|:--|
|[024.ファイル参照の抽出.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/03.%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE/024.%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%8F%82%E7%85%A7%E3%81%AE%E6%8A%BD%E5%87%BA.ipynb)|回答プログラムのGitHubリンク|
|[素人の言語処理100本ノック:24](https://qiita.com/segavvy/items/03b97eb6a39f5ae6aa34)|多くのソース部分のコピペ元|
|[ゼロから覚えるPython正規表現の基本とTips](https://qiita.com/FukuharaYohei/items/459f27f0d7bbba551af7)|当ノックで学習した内容を整理しました|
|[正規表現 HOWTO](https://docs.python.org/ja/3/howto/regex.html#regex-howto)|Python公式の正規表現How To|
|[re --- 正規表現操作](https://docs.python.org/ja/3/library/re.html)|Python公式のreパッケージ説明|
|[Help:早見表](https://ja.wikipedia.org/wiki/Help:%E6%97%A9%E8%A6%8B%E8%A1%A8)|Wikipediaの代表的なマークアップの早見表|
# 環境

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

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

|種類|バージョン|
|:--|:--|
|pandas|0.25.3|

# [第3章: 正規表現](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch3)
## 学習内容
> Wikipediaのページのマークアップ記述に正規表現を適用することで，様々な情報・知識を取り出します．
>> 正規表現, JSON, Wikipedia, InfoBox, ウェブサービス

## ノック内容
> Wikipediaの記事を以下のフォーマットで書き出したファイル[jawiki-country.json.gz](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/jawiki-country.json.gz)がある．

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

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

### [24. ファイル参照の抽出](http://www.cl.ecei.tohoku.ac.jp/nlp100/#sec24)
> 記事から参照されているメディアファイルをすべて抜き出せ．

### 課題補足(「ファイル」について)
[Help:早見表](https://ja.wikipedia.org/wiki/Help:%E6%97%A9%E8%A6%8B%E8%A1%A8)によると「ファイル」は`	[[ファイル:Wikipedia-logo-v2-ja.png|thumb|説明文]]`形式です。
以下の部分のファイル名を正規表現で抽出します。

```text:ファイル内の「ファイル」部分抜粋
|国章画像 = [[ファイル:Royal Coat of Arms of the United Kingdom.svg|85px|イギリスの国章]]\n
[[File:Battle of Waterloo 1815.PNG|thumb|left|[[ワーテルローの戦い]]での勝利により[[ナポレオン戦争]]は終止符が打たれ、[[パクス・ブリタニカ]]の時代が到来した。]]\n
[[File:The British Empire.png|thumb|250px|[[イギリス帝国]]統治下の経験を有する国・地域。現在の[[イギリスの海外領土]]は赤い下線が引いてある。]]\n
```

# 回答
## 回答プログラム [024.ファイル参照の抽出.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/03.%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE/024.%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%8F%82%E7%85%A7%E3%81%AE%E6%8A%BD%E5%87%BA.ipynb)

```python
import re
from pprint import pprint

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('イギリス')


# rを先頭にするとraw string でエスケープシーケンス無視
# 3重クォートで途中改行無視
# re.VERBOSEオプションを使うことによって、空白とコメント無視
# 非貪欲マッチにすることで、短い文字列を検索
pprint(re.findall(r'''
                  (?:File|ファイル)   # 非キャプチャ、'File'か'ファイル'
                  :                  # 非キャプチャ
                  (.+?)              # キャプチャ対象、任意の文字1文字以上、非貪欲
                  \|                 # 非キャプチャ、|をエスケープ
                  ''', wiki_body, re.VERBOSE))
```

## 回答解説
今回のメインは以下の部分です。

```python:
pprint(re.findall(r'''
                  (?:File|ファイル)   # 非キャプチャ、'File'か'ファイル'
                  :                  # 非キャプチャ
                  (.+?)              # キャプチャ対象、任意の文字1文字以上、非貪欲
                  \|                 # 非キャプチャ、|をエスケープ
                  ''', wiki_body, re.VERBOSE))
```

### 和集合(or)
`(?:File|ファイル)`の`|`はor記号です。
今回は「`File`または`ファイル`だったら」という意味です。

### 出力結果(実行結果)
プログラム実行すると以下の結果が出力されます。

```bash:出力結果
['Royal Coat of Arms of the United Kingdom.svg',
 'Battle of Waterloo 1815.PNG',
 'The British Empire.png',
 'Uk topo en.jpg',
 'BenNevis2005.jpg',
 'Elizabeth II greets NASA GSFC employees, May 8, 2007 edit.jpg',
 'Palace of Westminster, London - Feb 2007.jpg',
 'David Cameron and Barack Obama at the G20 Summit in Toronto.jpg',
 'Soldiers Trooping the Colour, 16th June 2007.jpg',
 'Scotland Parliament Holyrood.jpg',
 'London.bankofengland.arp.jpg',
 'City of London skyline from London City Hall - Oct 2008.jpg',
 'Oil platform in the North SeaPros.jpg',
 'Eurostar at St Pancras Jan 2008.jpg',
 'Heathrow T5.jpg',
 'Anglospeak.svg',
 'CHANDOS3.jpg',
 'The Fabs.JPG',
 'PalaceOfWestminsterAtNight.jpg',
 'Westminster Abbey - West Door.jpg',
 'Edinburgh Cockburn St dsc06789.jpg',
 'Canterbury Cathedral - Portal Nave Cross-spire.jpeg',
 'Kew Gardens Palm House, London - July 2009.jpg',
 '2005-06-27 - United Kingdom - England - London - Greenwich.jpg',
 'Stonehenge2007 07 30.jpg',
 'Yard2.jpg',
 'Durham Kathedrale Nahaufnahme.jpg',
 'Roman Baths in Bath Spa, England - July 2006.jpg',
 'Fountains Abbey view02 2005-08-27.jpg',
 'Blenheim Palace IMG 3673.JPG',
 'Liverpool Pier Head by night.jpg',
 "Hadrian's Wall view near Greenhead.jpg",
 'London Tower (1).JPG',
 'Wembley Stadium, illuminated.jpg']
```