2018年03月08日

言語処理100本ノックでPython入門 #22 - 正規表現のグループ

  
今日は、言語処理100本ノック 2015の問題22です。

■ 問題

問題20で作成したファイルを入力として、以下の問題を解きます。
22. カテゴリ名の抽出
記事のカテゴリ名を(行単位ではなく名前で)抽出せよ.

■ Pythonのコード
import json
import re
def readArticle(filename): with open(filename, 'r', encoding='utf8') as fin: return fin.read()
def getCategories(article): for s in article.split('\n'): m = re.match(r'\[\[Category:([^|]*)(|.*)?\]\]', s) if m: yield m.group(1)
def main(): article = readArticle('england-article.txt') for cat in getCategories(article): print(cat)
if __name__ == '__main__': main()
'england-article.txt'は問題20で作成したファイルです。これを入力ファイルとしています。


■ 正規表現のグループ

問題21のコードをすこし変えればできますね。 カテゴリの行は以下のようになっています。

[[Category:イギリス|*]]
[[Category:英連邦王国|*]]
[[Category:G8加盟国]]
[[Category:欧州連合加盟国]]
[[Category:海洋国家]]
[[Category:君主国]]
[[Category:島国|くれいとふりてん]]
[[Category:1801年に設立された州・地域]]

ここから、実際のカテゴリ名を抜き出します。

まずは、
m = re.match(r'\[\[Category:([^|]*)(|.*)?\]\]', s)
のようにして、matchオブジェクトを得ます。

カテゴリが下のような文字列だった場合は、|の前後で、グルーピングを分けるようにしています。
英連邦王国|*

その後、以下のように書けば、最初の()グループの中身が取得できます。
m.group(1) 

つまり、"英連邦王国|*" だったら、"英連邦王国"だけを取得できます。
r'\[\[Category:([^|]*)(|.*)?\]\]'
って表現がもう少し簡単にならないかなー。


■ 結果
イギリス
英連邦王国
G8加盟国
欧州連合加盟国
海洋国家
君主国
島国
1801年に設立された州・地域