2018年04月05日

言語処理100本ノックでPython入門 #33 - サ変接続の名詞


言語処理100本ノック 2015の問題33に挑戦です。

■ 問題


夏目漱石の小説『吾輩は猫である』の文章(neko.txt)をMeCabを使って形態素解析し,その結果をneko.txt.mecabというファイルに保存せよ.このファイルを用いて,以下の問に対応するプログラムを実装せよ. なお,問題37, 38, 39はmatplotlibもしくはGnuplotを用いるとよい.

33. サ変名詞
サ変接続の名詞をすべて抽出せよ.


■ Pythonのコード
import re

def analyze():
    lines = []
    sentence = []
    with open('neko.txt.mecab', 'r', encoding='utf8') as fin:
        for line in fin:
            words = re.split(r'\t|,|\n', line)
            if words[0] == 'EOS':
                if sentence:
                    lines.append(sentence)
                    sentence = []
                continue
            sentence.append({
                "surface": words[0],
                "base": words[7],
                "pos": words[1],
                "pos1": words[2],
            })
    return lines

def extractNouns(lines):
    for sentense in lines:
        seq = filter(lambda w: w['pos'] == '名詞' and w['pos1'] == 'サ変接続', sentense)
        yield from map(lambda w: w['surface'], seq)

def main():
    article = analyze()
    nouns = [surface for surface in extractNouns(article)]
    print(nouns[:50])

if __name__ == '__main__':
    main()


書いたコードについては、前回とほとんど同じなので、特筆すべき点はないです。

ラムダ式が少し複雑になったけど、タプルではなくて文字列を列挙しているので、プログラミングの観点からは、こちらのほうが易しいですね。

論理演算子の論理積が&&じゃなくてandなのがどうも面倒です。いつも&&と書いてエラーになっています。

ところで、このところ新しいし知識を仕入れなくても問題を解くことができるようになってきました。 文法で主要なのはあとはクラスくらいでしょうか? No.33以降の問題文を見てみると、第5章にクラスを実装せよという問題があるので、それまではクラスを使わずに解いていこうと思います。


■ 結果

プログラムでは取り出した先頭50個を表示しています。
なるほど、こういったものが、サ変接続の名詞なのか。
['見当', '記憶', '話', '装飾', '突起', '運転', '記憶', '分別', '決心', '我慢', '餓死', '訪問', '始末', '猶予', '遭遇', '我慢', '記憶', '返報', '勉強', '勉強', '昼寝', '珍重', '昼寝', '経験', '供', '供', '供', '供', '——', '——', '同居', '観察', '断言', '同衾', '供', '迫害', '尊敬', '生活', '剿滅', '議論', '所有', '憤慨', '観念', '御馳走', '掠奪', '代言', '我儘', '我儘', '失敗', '話']
  

Posted by gushwell at 22:10Comments(0)Python

2018年04月04日

言語処理100本ノックでPython入門 #32 - タプルをリスト内包表記で利用する


言語処理100本ノック 2015の問題32に挑戦です。

このあたりまで来ると、Pythonの言語機能を習得するという問題から、やりたいことをどうコードに落とし込むかという問題に焦点が移ってきていますね。

■ 問題


夏目漱石の小説『吾輩は猫である』の文章(neko.txt)をMeCabを使って形態素解析し,その結果をneko.txt.mecabというファイルに保存せよ.このファイルを用いて,以下の問に対応するプログラムを実装せよ. なお,問題37, 38, 39はmatplotlibもしくはGnuplotを用いるとよい.

32. 動詞の原形
動詞の原形をすべて抽出せよ.

■ Pythonのコード
import re

def analyze():
    lines = []
    sentence = []
    with open('neko.txt.mecab', 'r', encoding='utf8') as fin:
        for line in fin:
            words = re.split(r'\t|,|\n', line)
            if words[0] == 'EOS':
                if sentence:
                    lines.append(sentence)
                    sentence = []
                continue
            sentence.append({
                "surface": words[0],
                "base": words[7],
                "pos": words[1],
                "pos1": words[2],
            })
    return lines

def extractVerbs(lines):
    for sentense in lines:
        seq = filter(lambda w: w['pos'] == '動詞', sentense)
        yield from map(lambda w: (w['surface'], w['base']), seq)

def main():
    article = analyze()
    verbs = [(surface, base) for surface, base in extractVerbs(article)]
    print(verbs[:50])

if __name__ == '__main__':
    main()

■ ちょっとコードの解説


analyze関数は、問題30で作成したものと同じです。 せっかっくなので、動詞と原型を対で取得してみました。タプルを使っています。
(w['surface'], w['base'])
というコードを map関数の中で使って、yield fromで列挙しています。

main関数では、これを受け取り、リスト内包表記使ってリストに格納しています。
verbs = [(surface, base) for surface, base in extractVerbs(article)]
一つ目を取り出すならば、
print(verbs[0][0], verbs[0][1])
これで、
生れ 生れる
が表示されます。

ファイルに出力せよとか、表示せよとかの指定がないので、抽出したタプルのリストの先頭50個をprintに渡しています。

■ 結果

先頭50個を出力しています。
[('生れ', '生れる'), ('つか', 'つく'), ('し', 'する'), ('泣い', '泣く'), ('し', 'する'), ('いる', 'いる'), ('始め', '始める'), ('見', '見る'), ('聞く', '聞く'), ('捕え', '捕える'), ('煮', '煮る'), ('食う', '食う'), ('思わ', '思う'), ('載せ', '載せる'), ('られ', 'られる'), ('持ち上げ', '持ち上げる'), ('られ', 'られる'), ('し', 'する'), ('あっ', 'ある'), ('落ちつい', '落ちつく'), ('見', '見る'), ('見', '見る'), ('思っ', '思う'), ('残っ', '残る'), ('いる', 'いる'), ('さ', 'する'), ('れ', 'れる'), ('し', 'する'), ('逢っ', '逢う'), ('出会わ', '出会う'), ('し', 'する'), ('のみ', 'のむ'), ('なら', 'なる'), ('し', 'する'), ('いる', 'いる'), ('吹く', '吹く'), ('せ', 'する'), ('弱っ', '弱る'), ('飲む', '飲む'), ('知っ', '知る'), ('坐っ', '坐る'), ('おっ', 'おる'), ('する', 'する'), ('し', 'する'), ('始め', '始める'), ('動く', '動く'), ('動く', '動く'), ('分ら', '分る'), ('廻る', '廻る'), ('なる', 'なる')]
  
Posted by gushwell at 22:00Comments(0)Python

2018年04月02日

言語処理100本ノックでPython入門 #31 - yield fromが便利すぎる


言語処理100本ノック 2015の問題31を解きました。

■ 問題

夏目漱石の小説『吾輩は猫である』の文章(neko.txt)をMeCabを使って形態素解析し,その結果をneko.txt.mecabというファイルに保存せよ.このファイルを用いて,以下の問に対応するプログラムを実装せよ. なお,問題37, 38, 39はmatplotlibもしくはGnuplotを用いるとよい.

31. 動詞
動詞の表層形をすべて抽出せよ.


■ Pythonのコード
import re

def analyze():
    lines = []
    sentence = []
    with open('neko.txt.mecab', 'r', encoding='utf8') as fin:
        for line in fin:
            words = re.split(r'\t|,|\n', line)
            if words[0] == 'EOS':
                if sentence:
                    lines.append(sentence)
                    sentence = []
                continue
            sentence.append({
                "surface": words[0],
                "base": words[7],
                "pos": words[1],
                "pos1": words[2],
            })
    return lines

def extractVerbs(lines):
    for sentense in lines:
        seq = filter(lambda w: w['pos'] == '動詞', sentense)
        yield from map(lambda w: w['surface'], seq)

def main():
    article = analyze()
    verbs = [surface for surface in extractVerbs(article)]
    print(verbs[:50])
    print('-----')

if __name__ == '__main__':
    main()

■ ちょっとコードの解説


analyze関数は問題30で書いたものと同じです。このanalyzeの結果を使い、今回書いたextractVerbs関数で、動詞だけを抜き出しています。

キー'pos'の値を見れば、動詞かどうかが判断できます。ちなみに pos は、品詞: part of speech の頭文字だと思われます。

extractVerbs関数は、以下のforとifを使ったコードと同等です。
def extractVerbs(lines):
    for sentense in lines:
        for word in sentense:
            if word['pos'] == '動詞':
                yield word['surface']
上のコードは、for文で回しているだけなので、何も難しいことはやっていません。

抜き出した動詞は、yieldで列挙しています。 今回はfilter関数とmap関数を使って書いてみたのですが、1行に書きたいけど、1行だと長くなっちゃうし読みやすいとは言えないかな。
C#のLINQみたいに、メソッドチェーンできればいいのですが...

でも yield from 構文はすごく便利ですね。これはC#にも欲しい機能です。 yield from 構文が無いと、以下のように書かなくてはなりません。
seq = filter(lambda w: w['pos'] == '動詞', sentense)
seq = map(lambda w: w['surface'], seq)
for w in seq:
    yield w

main関数では、リスト内包表記使ってリストにしています。

■ 結果

取り出した結果の先頭50個を表示しています。
['生れ', 'つか', 'し', '泣い', 'し', 'いる', '始め', '見', '聞く', '捕え', '煮', '食う', '思わ', '載せ', 'られ', '持ち上げ', 'られ', 'し', 'あっ', '落ちつい', '見', '見', '思っ', '残っ', 'いる', 'さ', 'れ', 'し', '逢っ', '出会わ', 'し', 'のみ', 'なら', 'し', 'いる', '吹く', 'せ', '弱っ', '飲む', '知っ', '坐っ', 'おっ', 'する', 'し', '始め', '動く', '動く', '分ら', '廻る', 'なる']
  
Posted by gushwell at 22:34Comments(0)Python

2018年03月30日

言語処理100本ノックでPython入門 #30 - mecabを使って形態素解析


今日から言語処理100本ノック 2015「第4章 形態素解析」に入ります。

僕にとっては未知の分野、どんな問題なのか楽しみです。

■ 問題

夏目漱石の小説『吾輩は猫である』の文章(neko.txt)をMeCabを使って形態素解析し,その結果をneko.txt.mecabというファイルに保存せよ.このファイルを用いて,以下の問に対応するプログラムを実装せよ. なお,問題37, 38, 39はmatplotlibもしくはGnuplotを用いるとよい.

30. 形態素解析結果の読み込み
形態素解析結果(neko.txt.mecab)を読み込むプログラムを実装せよ.ただし,各形態素は表層形(surface),基本形(base),品詞(pos),品詞細分類1(pos1)をキーとするマッピング型に格納し,1文を形態素(マッピング型)のリストとして表現せよ.
第4章の残りの問題では,ここで作ったプログラムを活用せよ.


■ mecabのインストール

Windowsの場合は、http://taku910.github.io/mecab/ から、mecab-0.996.exe をダウンロードしてインストールするだけみたいです。Unixdだと自分でビルドするようなことが書いてありましたが、Macの場合は、brewコマンドでインストールできるみたいです。

で、以下のコマンドを投入。
brew install mecab
 
でも、失敗、どうもXCodeとhomebrewのバージョンが古いみたいなメッセージがでました。

で、まずは、XCodeをAppStoreからインストールします。
けっこうな時間がかかりました。
インストールしたあと、
sudo xcodebuild -license accept
でライセンスを承認。

その後、以下のコマンドでbrewをアップグレード
brew upgrade

brewが最新のものになったので、再度mecabと辞書をインストールします。 

brew install mecab 
brew install mecab-ipadic

これで準備完了です。

■ mecabファイルの作成

Pythonからmecabを呼び出すこともできるようですが、ここではコマンドラインから、neko.txtを読み込み、neko.txt.mecabを作成します。 neko.txtのあるフォルダに移動し、以下のコマンドを実行

mecab neko.txt -o neko.txt.mecab

neko.txt.mecabを作成すれば良いだけなので、これはすんなり行きました。 以下のようなファイルが作成されます。一部だけ抜粋して掲載
一    名詞,数,*,*,*,*,一,イチ,イチ
EOS
EOS
     記号,空白,*,*,*,*, , , 
吾輩    名詞,代名詞,一般,*,*,*,吾輩,ワガハイ,ワガハイ
は    助詞,係助詞,*,*,*,*,は,ハ,ワ
猫    名詞,一般,*,*,*,*,猫,ネコ,ネコ
で    助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ
ある    助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル
。    記号,句点,*,*,*,*,。,。,。
EOS
名前    名詞,一般,*,*,*,*,名前,ナマエ,ナマエ
は    助詞,係助詞,*,*,*,*,は,ハ,ワ
まだ    副詞,助詞類接続,*,*,*,*,まだ,マダ,マダ
無い    形容詞,自立,*,*,形容詞・アウオ段,基本形,無い,ナイ,ナイ
。    記号,句点,*,*,*,*,。,。,。
EOS
EOS
     記号,空白,*,*,*,*, , , 
どこ    名詞,代名詞,一般,*,*,*,どこ,ドコ,ドコ
で    助詞,格助詞,一般,*,*,*,で,デ,デ
生れ    動詞,自立,*,*,一段,連用形,生れる,ウマレ,ウマレ
た    助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
か    助詞,副助詞/並立助詞/終助詞,*,*,*,*,か,カ,カ
とんと    副詞,一般,*,*,*,*,とんと,トント,トント
見当    名詞,サ変接続,*,*,*,*,見当,ケントウ,ケントー
が    助詞,格助詞,一般,*,*,*,が,ガ,ガ
つか    動詞,自立,*,*,五段・カ行イ音便,未然形,つく,ツカ,ツカ
ぬ    助動詞,*,*,*,特殊・ヌ,基本形,ぬ,ヌ,ヌ
。    記号,句点,*,*,*,*,。,。,。
EOS
■ mecabファイルの形式

http://taku910.github.io/mecab/ を読むと、mecabの出力フォーマットは、以下の通りです。
表層形\t品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音
これが複数行続いています。文の終わりには、EOSという行があります。

問題にある「基本形」がどの項目を指しているのかわからないのですが、「原形」ってのがあるから、たぶんこのことだと思います。

mecabを使ってみて、株式会社平和情報センターが開発したHAPPINESSという日本語を分かち書きをするソフトを使って文章のなかからキーワードを抽出するプログラムをはるか昔に書いたことを思い出しました。 その頃のプラットホームはホストコンピュータでした。懐かしいなー。

■ Pythonのコード
import re

def analyze():
    lines = []
    sentence = []
    with open('neko.txt.mecab', 'r', encoding='utf8') as fin:
        for line in fin:
            words = re.split(r'\t|,|\n', line)
            if words[0] == 'EOS':
                if sentence:
                    lines.append(sentence)
                    sentence = []
                continue
            sentence.append({
                "surface": words[0],
                "base": words[7],
                "pos": words[1],
                "pos1": words[2],
            })
    return lines

def main():
    article = analyze()
    print(article[0])
    print()
    print(article[1])
    print()
    print(article[2])

if __name__ == '__main__':
    main()

■ 採用するデータの構造


関数analyzeが今回の目的のコードで、ここで問題が求めているデータを作成しています。


問題文のマッピング型ってのは、辞書形式のことらしいです。なので、ファイルの1行をマッピング型に格納し、1文をリストに格納することとします。

問題文は、「1文を形態素(マッピング型)のリストとして表現せよ」とありますが、ファイルには複数文のデータがあるわけだから、さらにこれをリストに格納するってことなのだと判断しました。
文章:リスト型 (文が複数格納される)
    1文:リスト型 (形態素が複数格納される)
        形態素:マッピング型 (surface,base, pos, pos1をキーとする)

■ 形態素のマッピング型を作成


読み込んだ1行の分割は、正規表現ライブラリの re.splitを使って分割します。
words = re.split(r'\t|,|\n', line)
この1行が1形態素になります。 これをsurface, base, pos, pos1をキーとするマッピング型にするということで、たぶん以下のようなオブジェクトにすればいいのだと思います。
{
    "surface": words[0],
    "base": words[7],
    "pos": words[1],
    "pos1": words[2],
}
C#だと、こういった場合は、4つのプロパティを持つクラスを定義することになると思いますが、Pythonだとこうするのが普通なのかな? JavaScriptのオブジェクトっぽいです。

このオブジェクトを1文を表すsentenceリストにappendメソッドで追加します。 

■ 文単位に分割する


入力データに'EOS'が来たら、それまでため込んでいた1文のデータ(sentence)を、linesに追加。
最初は以下のように書きました。
# if len(sentense) > 0: って書いたらpylintに怒られた
if sentence:
    lines.append(sentence)
    sentence.clear()  # 次の文を格納するために初期化
continue
でも、実行してみると、次のような結果になったので「なんで?」ってなってしまいました。
[]
[]
[]

そりゃそうですよね。
linesにアペンドしたものをクリアしちゃってるんだから。
なので、以下のように書き直します。

if sentence:
    lines.append(sentence)
    sentence = []
continue
これでOKです。
以下のようにオブジェクトの複製を作る方法もありですが、ちょっと効率が悪そうかな。
if sentence:
    lines.append(sentence.copy())
    sentence.clear()
continue


■ 結果

作成したプログラムでは、確認のために最初の3文の形態素を出力しています。

[{'surface': '一', 'base': '一', 'pos': '名詞', 'pos1': '数'}]

[{'surface': '\u3000', 'base': '\u3000', 'pos': '記号', 'pos1': '空白'}, {'surface': '吾輩', 'base': '吾輩', 'pos': '名詞', 'pos1': '代名詞'}, {'surface': 'は', 'base': 'は', 'pos': '助詞', 'pos1': '係助詞'}, {'surface': '猫', 'base': '猫', 'pos': '名詞', 'pos1': '一般'}, {'surface': 'で', 'base': 'だ', 'pos': '助動詞', 'pos1': '*'}, {'surface': 'ある', 'base': 'ある', 'pos': '助動詞', 'pos1': '*'}, {'surface': '。', 'base': '。', 'pos': '記号', 'pos1': '句点'}]

[{'surface': '名前', 'base': '名前', 'pos': '名詞', 'pos1': '一般'}, {'surface': 'は', 'base': 'は', 'pos': '助詞', 'pos1': '係助詞'}, {'surface': 'まだ', 'base': 'まだ', 'pos': '副詞', 'pos1': '助詞類接続'}, {'surface': '無い', 'base': '無い', 'pos': '形容詞', 'pos1': '自立'}, {'surface': '。', 'base': '。', 'pos': '記号', 'pos1': '句点'}]
  
Posted by gushwell at 21:40Comments(0)Python

2018年03月25日

言語処理100本ノックでPython入門 #29 - HttpGetでJSONデータを取得


今日は、言語処理100本ノック 2015の第3章最後の問題 No.29です。

■ 問題

問題20で作成したファイルを入力として、以下の問題を解きます。
29. 国旗画像のURLを取得する
テンプレートの内容を利用し,国旗画像のURLを取得せよ.(ヒント: MediaWiki APIのimageinfoを呼び出して,ファイル参照をURLに変換すればよい)

■ Pythonのコード
import json
import re
import urllib.request
import urllib.parse

def readArticle(filename):
    with open(filename, 'r', encoding='utf8') as fin:
        return fin.read()

def getImageFileName(article):
    basicInfo = re.search(r'\{\{基礎情報(.+?)\}\}\n', article, re.DOTALL).group(1)
    pat = r'^\|国旗画像\s*=\s*(.+?)\n'
    reg = re.compile(pat, re.MULTILINE | re.DOTALL)
    m = reg.search(basicInfo)
    return m.group(1)

def getImage(finename):
    url = 'https://ja.wikipedia.org/w/api.php?' \
        + 'action=query' \
        + '&format=json' \
        + '&titles=File:' + urllib.parse.quote(finename) \
        + '&prop=imageinfo' \
        + '&iiprop=url'
    with urllib.request.urlopen(url) as res:
        data = json.loads(res.read().decode())
        return data['query']['pages']['-1']['imageinfo'][0]['url']


def main():
    # england-article.txtは、問題20(nlp20.py)で作成したファイル
    article = readArticle('england-article.txt')  
    fname = getImageFileName(article)
    print(getImage(fname))

if __name__ == '__main__':
    main()

■ 今回のトピック

ソースコードの1文を複数行に分ける

ソースコード上で、複数行にわたる文字列を連結するには、行末に \ が必要。
url = 'https://ja.wikipedia.org/w/api.php?' \
    + 'action=query' \
    + '&format=json' \
    + '&titles=File:' + urllib.parse.quote(finename) \
    + '&prop=imageinfo' \
    + '&iiprop=url'

最初は、この \ を書かなかったら、
E0001:unexpected indent

が表示されてしばらく意味わかりませんでした。

文字列連結にかかわらず、本来1行のものを複数行に分ける場合は、\ が必要ということらしいです。 そういえば、No13 で既に使ってました。すっかり忘れています。

URLエンコード
import urllib.parse

encoded = urllib.parse.quote(s)

文字列sをurlエンコードします。
quoteというメソッド名にものすごい違和感を感じるのですが、それは僕の英語力がないせいでしょうか?


Http Get
import urllib.request

with urllib.request.urlopen(url) as res:
    bytes = res.read()

指定したurlからHttp Getでデータを取得します。readメソッドで読み込んだデータはbyte配列です。


byte配列をstringにする


byte配列をstringにするには、decodeメソッドを呼び出します。

with urllib.request.urlopen(url) as res:
    data = json.loads(res.read().decode())

これで得た文字列を、json.loadsに渡し、jsonを辞書形式に変換します。


ちなみに、取得したjsonデータは以下の通りです。

{
    'query': {
        'normalized': [
            {'from': 'File:Flag of the United Kingdom.svg', 
             'to': 'ファイル:Flag of the United Kingdom.svg'
            }
        ], 
        'pages': {
            '-1': {
                'missing': '', 
                'known': '', 
                'title': 'ファイル:Flag of the United Kingdom.svg', 
                'ns': 6, 
                'imagerepository': 'shared', 
                'imageinfo': [
                    {
                        'descriptionshorturl': 'https://commons.wikimedia.org/w/index.php?curid=347935', 
                        'descriptionurl': 'https://commons.wikimedia.org/wiki/File:Flag_of_the_United_Kingdom.svg', 
                        'url': 'https://upload.wikimedia.org/wikipedia/commons/a/ae/Flag_of_the_United_Kingdom.svg'
                    }
                ]
            }
        }
    }, 
    'continue': {
        'continue': '||', 
        'iistart': '2007-09-03T09:51:34Z'
    }
}
このデータの中から、以下のようにして国旗画像のURLを取得します。階層構造の深いところにあるので面倒です。

js['query']['pages']['-1']['imageinfo'][0]['url']


■ 結果
https://upload.wikimedia.org/wikipedia/commons/a/ae/Flag_of_the_United_Kingdom.svg



これで、第3章が終わりました。
まだ3割。先が長いです。 そもそも僕の実力で最後まで解くことができるのでしょうか。 モチベーションが継続するかも問題だなー。  
Posted by gushwell at 22:46Comments(0)Python

2018年03月21日

言語処理100本ノックでPython入門 #28 - いろいろな正規表現



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

■ 問題

問題20で作成したファイルを入力として、以下の問題を解きます。
28. MediaWikiマークアップの除去 27の処理に加えて,テンプレートの値からMediaWikiマークアップを可能な限り除去し,国の基本情報を整形せよ.

■ Pythonのコード
import re

def readArticle(filename):
    with open(filename, 'r', encoding='utf8') as fin:
        return fin.read()

def getBasicInfo(article):
    basicInfo = re.search(r'\{\{基礎情報(.+?)\}\}\n', article, re.DOTALL).group(1)
    pat = r'^\|(.+?)\s*=\s*(.+?)(?<!<br/>)\n'
    reg = re.compile(pat, re.MULTILINE | re.DOTALL)
    wdict = {}
    for k, v in reg.findall(basicInfo):
        v = re.sub(r"''('|''')([^']+?)''+", r"\2", v)
        v = re.sub(r"\[\[(?:[^\]]+\|)?([^:]+?)\]\]", r"\1", v)
        v = re.sub(r"\[http(?:[^\]]+? )?(.+?)\]", r"\1", v)
        v = re.sub(r"#REDIRECT \[\[([^\[]+?)\]\]", r"\1", v)
        v = re.sub(r"^===*\s*(.+)\s*=", r"\1", v)
        v = re.sub(r"^(?:\*|#|;)+\s*([^\n]+?)$", r"\1", v, flags=re.MULTILINE)
        v = re.sub(r"{{(?:[^\{]+\|)?([^\|]+?)}}", r"\1", v)
        v = re.sub(r"<[^>]+>", r" ", v)
        wdict[k] = v

    return wdict


def main():
    # england-article.txtは、問題20(nlp20.py)で作成したファイル
    article = readArticle('england-article.txt')    
    dic = getBasicInfo(article)
    dic = sorted(dic.items(), key=lambda x: x[0])
    for item, v in dic:
        print(item, ':', v)

if __name__ == '__main__':
    main()


■ コードについて一言

「可能な限り除去し」ということで、わかる範囲で除去してみました。これまでの、正規表現の総復習みたいなコードですね。かなり力業的なコードです。 ひとつ一つの説明は省きますが、一つだけ、flags=re.MULTILINEを付けているものがあります。これは、記事の中にある箇条書きに対応するためです。
 v = re.sub(r"^(?:\*|#|;)+\s*([^\n]+?)$", r"\1", v, flags=re.MULTILINE)
compileしないで、 MULTILINEオプションを指定しています。


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