Pythonでpykakasiを使用して文章から母音と「ん」を抽出するやつ

# 1.はじめに
タイトルの通り、Pythonで`pykakasi`を使用して文章から母音と「ん」を抽出するやつです。
メモ書き程度で雑な文章ですが、備忘録として残しておきます。

# 2.pykakasiとは
日本語の文字・文章をひらがな/カタカナ/ローマ字(ヘボン式/訓令式/パスポート)に変換出来るようにするライブラリです。

# 3.pykakasiをインストール
```
pip install pykakasi
```

# 4.pykakasiをimport
```Python:ExtractVowelAndN.py
# pykakasiをimport
import pykakasi
kakasi = pykakasi.kakasi()
```

# 5.例文
```Python:ExtractVowelAndN.py
# 例文
text = '々々々あ々々々諸々々々徐々々々なにぬねのにゃにゅんにょん'
```

# 6.文章中の「々(繰り返し文字)」を処理
```Python:ExtractVowelAndN.py
# textの先頭の'々'を削除したうえで、textの'々'を1文字前の文字に置換する関数
def replace_kurikaesi(text):
  # textの先頭に'々'がある場合、0文字目～'々'が出現しなくなるまで'々'を削除
  text = text.lstrip('々')
  # textをリストに変換
  text_list = list(text)
  # 文字数カウント
  word_cnt = 0
  # text_listから文字を1文字ずつ取り出して'々'かどうかを判別
  for word in text_list:
    # wordが'々'だった場合、wordの'々'を1文字前の文字に置換
    if word == '々':
      text_list[word_cnt] = text_list[word_cnt-1]
    word_cnt += 1
  # text_listをリストから文字列に戻す
  replaced_kurikaesi_text = "".join(text_list)
  # textの'々'を1文字前の文字に置換したtextを返す
  return replaced_kurikaesi_text

# textの先頭の'々'を削除したうえで、textの'々'を1文字前の文字に置換
replaced_kurikaesi_text = replace_kurikaesi(text)
print(replaced_kurikaesi_text)
```
`pykakasi`で日本語の文字・文章をローマ字に変換した場合、「々」は「`'(kurikaesi)'`」に変換されてしまうため、事前に上記の処理を行います。

#### 上記実行結果
```
ああああ諸諸諸諸徐徐徐徐なにぬねのにゃにゅんにょん
```
「々(繰り返し文字)」を処理出来ました。

# 7.文章を指定した種類(ひらがな)に変換
```Python:ExtractVowelAndN.py
# textをword_typeで指定した種類(ひらがな、ローマ字等)の文字列に変換して、空欄で単語ごとに区別した状態で連結したtextを返す関数
def convert_word_type_text(text, word_type):
  # 文章をkakasiに突っ込んで、単語ごとに分解されたリストを取得(単語は辞書型で色々な形式に変換された状態で格納されている)
  word_list = kakasi.convert(text)
  # word_listからword_typeで指定された種類(ひらがな、ローマ字等)の文字列のみを抽出
  word_list_len = len(word_list)
  word_type_word_list = [word_list[cnt][word_type] for cnt in range(word_list_len)]
  # 単語間に空欄を追加して単語ごとに区別した状態で単語を連結する
  word_type_text = " ".join(word_type_word_list)
  # word_typeで指定した種類の文字列に変換して、空欄で単語ごとに区別した状態で連結したtextを返す
  return word_type_text

# replaced_kurikaesi_textをひらがな('hira')に変換して、空欄で単語ごとに区別した状態で連結
hira_text = convert_word_type_text(replaced_kurikaesi_text, 'hira')
print(hira_text)
```
ひらがなを指定します。
この関数は後ほど[9.文章を指定した種類(ローマ字)に変換](https://qiita.com/milky04/items/1a13583acc603d224339#9%E6%96%87%E7%AB%A0%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E7%A8%AE%E9%A1%9E%E3%83%AD%E3%83%BC%E3%83%9E%E5%AD%97%E3%81%AB%E5%A4%89%E6%8F%9B)でまた使用します。

#### 上記実行結果
```
ああああ もろもろ もろもろ じょじょ じょじょ なにぬねのにゃにゅんにょん
```
ひらがなに変換出来ました。

# 8.文章中の「にゃ」「にゅ」「にょ」をそれぞれの母音(「あ」「う」「お」)に変換
```Python:ExtractVowelAndN.py
# ひらがなのtextの'にゃ','にゅ','にょ'をそれぞれの母音('あ','う','お')に変換する関数
def convert_nyanyunyo_to_vowel(text):
  # 'にゃ','にゅ','にょ'にそれぞれ対応する母音('あ','う','お')の辞書
  nyanyunyo_vowel_dict =  {'にゃ':'あ', 'にゅ':'う', 'にょ':'お'}
  # 'にゃ','にゅ','にょ'をそれぞれ対応する母音に変換
  for key, value in nyanyunyo_vowel_dict.items():
    text = text.replace(key, value)
  # 'にゃ','にゅ','にょ'をそれぞれの母音に変換したtextを返す
  return text

# hira_textの'にゃ','にゅ','にょ'をそれぞれの母音('あ','う','お')に変換
hira_text = convert_nyanyunyo_to_vowel(hira_text)
print(hira_text)
```
「にゃ」「にゅ」「にょ」は後述の[10.文章から母音と「ん」を抽出](https://qiita.com/milky04/items/1a13583acc603d224339#10%E6%96%87%E7%AB%A0%E3%81%8B%E3%82%89%E6%AF%8D%E9%9F%B3%E3%81%A8%E3%82%93%E3%82%92%E6%8A%BD%E5%87%BA)ではうまく母音抽出出来ないため、例外的にここでそれぞれの母音に変換します。
(例:「にゃ(`'nya'`)」の場合、「あ(`'a'`)」とはならず「んあ(`'na'`)」となってしまう。)

#### 上記実行結果
```
ああああ もろもろ もろもろ じょじょ じょじょ なにぬねのあうんおん
```
「にゃ」「にゅ」「にょ」をそれぞれの母音に変換出来ました。

# 9.文章を指定した種類(ローマ字(訓令式))に変換
```Python:ExtractVowelAndN.py
# hira_textをローマ字('kunrei'(訓令))に変換して、空欄で単語ごとに区別した状態で連結
kunrei_text = convert_word_type_text(hira_text, 'kunrei')
print(kunrei_text)
```
先ほど[7.文章を指定した種類(ひらがな)に変換](https://qiita.com/milky04/items/1a13583acc603d224339#7%E6%96%87%E7%AB%A0%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E7%A8%AE%E9%A1%9E%E3%81%B2%E3%82%89%E3%81%8C%E3%81%AA%E3%81%AB%E5%A4%89%E6%8F%9B)で定義した関数を使用します。
ローマ字(訓令式)を指定します。

#### 上記実行結果
```
aaaa   moromoro   moromoro   jojo   jojo   naninunenoaun'on
```
ローマ字に変換出来ました。

# 10.文章から母音と「ん」を抽出
```Python:ExtractVowelAndN.py
# ローマ字のtextから母音と"ん"をひらがなに変換したうえで抽出する関数
def extract_vowel_and_n(text):
  # ローマ字に対応するひらがなの母音と"ん"の辞書
  hiragana_vowel_and_n_dict = {'a':'あ','i':'い','u':'う','e':'え','o':'お','n':'ん'}
  # hiragana_vowel_and_n_dictのコピーを作成
  hiragana_vowel_dict = hiragana_vowel_and_n_dict.copy()
  # hiragana_vowel_dictから"ん"を削除して母音のみの辞書を作成
  hiragana_vowel_dict.pop('n')
  # 出力用の空のvowel_and_n_textを作成
  vowel_and_n_text = ""
  # 文字数カウント
  word_cnt = 0
  # ローマ字のtextからローマ字の母音と"ん"を取り出し
  for word in text:
    word_cnt += 1
    # wordがローマ字の母音なら対応するひらがなの母音をvowel_and_n_textに加える。
    # または'n'かつ最後の文字or'n'の後ろに"'"が付いているor'n'の後ろの文字が母音ではないなら「ん」確定なのでvowel_and_n_textに加える(それ以外はな行の文字なのでpass)。
    if (word in hiragana_vowel_dict) or ((word == 'n') and ((len(text) == word_cnt) or (text[word_cnt] == "'") or (text[word_cnt] not in hiragana_vowel_dict))):
      vowel_and_n_text += hiragana_vowel_and_n_dict[word]
    # 母音と"ん"以外ならpass
    else:
      pass
  # 母音と"ん"を抽出したtextを返す
  return vowel_and_n_text

# kunrei_textから母音と"ん"をひらがなに変換したうえで抽出
vowel_and_n_text = extract_vowel_and_n(kunrei_text)
# 母音と"ん"を抽出した文字列を出力
print(vowel_and_n_text)
```

#### 上記実行結果
```
ああああおおおおおおおおおおおおあいうえおあうんおん
```
母音と「ん」を抽出できました。

# 11.コード全文
```Python:ExtractVowelAndN.py
# pykakasiをimport
import pykakasi
kakasi = pykakasi.kakasi()

# textの先頭の'々'を削除したうえで、textの'々'を1文字前の文字に置換する関数
def replace_kurikaesi(text):
  # textの先頭に'々'がある場合、0文字目～'々'が出現しなくなるまで'々'を削除
  text = text.lstrip('々')
  # textをリストに変換
  text_list = list(text)
  # 文字数カウント
  word_cnt = 0
  # text_listから文字を1文字ずつ取り出して'々'かどうかを判別
  for word in text_list:
    # wordが'々'だった場合、wordの'々'を1文字前の文字に置換
    if word == '々':
      text_list[word_cnt] = text_list[word_cnt-1]
    word_cnt += 1
  # text_listをリストから文字列に戻す
  replaced_kurikaesi_text = "".join(text_list)
  # textの'々'を1文字前の文字に置換したtextを返す
  return replaced_kurikaesi_text

# textをword_typeで指定した種類(ひらがな、ローマ字等)の文字列に変換して、空欄で単語ごとに区別した状態で連結したtextを返す関数
def convert_word_type_text(text, word_type):
  # 文章をkakasiに突っ込んで、単語ごとに分解されたリストを取得(単語は辞書型で色々な形式に変換された状態で格納されている)
  word_list = kakasi.convert(text)
  # word_listからword_typeで指定された種類(ひらがな、ローマ字等)の文字列のみを抽出
  word_list_len = len(word_list)
  word_type_word_list = [word_list[cnt][word_type] for cnt in range(word_list_len)]
  # 単語間に空欄を追加して単語ごとに区別した状態で単語を連結する
  word_type_text = " ".join(word_type_word_list)
  # word_typeで指定した種類の文字列に変換して、空欄で単語ごとに区別した状態で連結したtextを返す
  return word_type_text

# ひらがなのtextの'にゃ','にゅ','にょ'をそれぞれの母音('あ','う','お')に変換する関数
def convert_nyanyunyo_to_vowel(text):
  # 'にゃ','にゅ','にょ'にそれぞれ対応する母音('あ','う','お')の辞書
  nyanyunyo_vowel_dict =  {'にゃ':'あ', 'にゅ':'う', 'にょ':'お'}
  # 'にゃ','にゅ','にょ'をそれぞれ対応する母音に変換
  for key, value in nyanyunyo_vowel_dict.items():
    text = text.replace(key, value)
  # 'にゃ','にゅ','にょ'をそれぞれの母音に変換したtextを返す
  return text

# ローマ字のtextから母音と"ん"をひらがなに変換したうえで抽出する関数
def extract_vowel_and_n(text):
  # ローマ字に対応するひらがなの母音と"ん"の辞書
  hiragana_vowel_and_n_dict = {'a':'あ','i':'い','u':'う','e':'え','o':'お','n':'ん'}
  # hiragana_vowel_and_n_dictのコピーを作成
  hiragana_vowel_dict = hiragana_vowel_and_n_dict.copy()
  # hiragana_vowel_dictから"ん"を削除して母音のみの辞書を作成
  hiragana_vowel_dict.pop('n')
  # 出力用の空のvowel_and_n_textを作成
  vowel_and_n_text = ""
  # 文字数カウント
  word_cnt = 0
  # ローマ字のtextからローマ字の母音と"ん"を取り出し
  for word in text:
    word_cnt += 1
    # wordがローマ字の母音なら対応するひらがなの母音をvowel_and_n_textに加える。
    # または'n'かつ最後の文字or'n'の後ろに"'"が付いているor'n'の後ろの文字が母音ではないなら「ん」確定なのでvowel_and_n_textに加える(それ以外はな行の文字なのでpass)。
    if (word in hiragana_vowel_dict) or ((word == 'n') and ((len(text) == word_cnt) or (text[word_cnt] == "'") or (text[word_cnt] not in hiragana_vowel_dict))):
      vowel_and_n_text += hiragana_vowel_and_n_dict[word]
    # 母音と"ん"以外ならpass
    else:
      pass
  # 母音と"ん"を抽出したtextを返す
  return vowel_and_n_text

# 例文
text = '々々々あ々々々諸々々々徐々々々なにぬねのにゃにゅんにょん'
# textの先頭の'々'を削除したうえで、textの'々'を1文字前の文字に置換
replaced_kurikaesi_text = replace_kurikaesi(text)
# replaced_kurikaesi_textをひらがな('hira')に変換して、空欄で単語ごとに区別した状態で連結
hira_text = convert_word_type_text(replaced_kurikaesi_text, 'hira')
# hira_textの'にゃ','にゅ','にょ'をそれぞれの母音('あ','う','お')に変換
hira_text = convert_nyanyunyo_to_vowel(hira_text)
# hira_textをローマ字('kunrei'(訓令))に変換して、空欄で単語ごとに区別した状態で連結
kunrei_text = convert_word_type_text(hira_text, 'kunrei')
# kunrei_textから母音と"ん"をひらがなに変換したうえで抽出
vowel_and_n_text = extract_vowel_and_n(kunrei_text)
# 母音と"ん"を抽出した文字列を出力
print(vowel_and_n_text)
```
上記コピペでそのまま使用できます。

#### 上記実行結果
```
ああああおおおおおおおおおおおおあいうえおあうんおん
```

# 12.おわりに
改善案やアドバイス等ありましたらコメントまたは[Twitter](https://twitter.com/as9784048914215)で指摘して頂けると幸いです。

# 13.参考記事
- [【Python】漢字をローマ字・ひらがな・カタカナに自動変換する方法（pykakasi）](https://office54.net/python/module/pykakasi-kanji-convert)