【第1回】Python3とMeCabを使ってHTMLで自動ルビ振りを実現させるためへの挑戦

投稿者: | 2018年6月19日

はじめに

これはPython3とMeCabを使ってHTMLで自動ルビ振りを実現させるための挑戦記録である。新しいサイトを運用するにあたってどうしても漢字にふりがなを入れたくなったんだけど、自動でルビふりしてくれるサービスで実用的なのは「テキスト解析:ルビ振り – Yahoo!デベロッパーネットワーク」なんだけど、APIとか制限とかでちょっと面倒だし、最終目的としては、Wordpressの投稿を表示時に自動ルビふりさせたいので自分で構築するのいいかなと思った。

PythonとMeCabの組み合わせで自動ルビふり

色々検索すると自前で自動ルビふりででふりがなをHTMLのタグで表現できるのはMeCabで解析して何かしらのプログラム言語で表示させるのがいいかなと。そこで出会ったのが「Python3からMecabを使いhtmlで自動でふりがなをふるツールを作る」で紹介されているPythonとMeCabの組み合わせでの自動ルビふりできる手法だった。

既存の自動ルビふりプログラムの問題点

上記のサイトである程度は自動でふりがなを振れるが、いくつかの問題点があったので実用できない。

問題点のテキストサンプル

下記のものは先ほどのサイトで紹介されているプログラムを実行したものだ。

埋め立うめた

男の子おとこのこ

見つみつかっていない

お正月

これらは上記のものでは送り仮名の処理を末尾の2文字分だけを処理するように作られているので、MeCabで解析され分割された中に「ひらがな」が含まれていてもルビは振られない。

また、送り仮名が3文字以上の場合、後ろから3文字目以前の送り仮名は漢字側に含まれてしまっている。

他に、ふりがなを振るかどうかを「単語の先頭に漢字があるかどうか」で判断しているので「お正月」のように「ひらがな」が先頭にある単語では、そもそも「ふりがな」を振ってくれない。


スポンサーリンク

問題点を解決して行く

今回の「実用的な自動ルビふりプログラム」を作って行くにあたっては上記のサイトのプログラムを参考にしながら改善して実現させていこうと思う。

ということで、まずは先にお手本にするプログラムをQiita上で紹介された「@kt-tsutsumi」様に感謝の意の込めて使わさせていただきます。

参考コードの紹介

ちなみにこちらが今回参照させていただくコードになります。

#!/usr/local/src/pyenv/shims/python
# -*- coding: utf_8 -*-
import sys
import MeCab
import re
def henkan(text) :
    hiragana=[chr(i) for i in range(12353, 12436)]
    katakana=[chr(i) for i in range(12449, 12532)]
    kana=""
    #読み仮名のカタかなをひらがなに
    for text in list(text):
        for i in range(83):
            if text == katakana[i]:
                kana+=hiragana[i]
    return kana
def tohensu(origin,kana) :
    origin="".join(origin)
    kana="".join(kana)
    return origin,kana
def kanadelete(origin,kana) :
    origin=list(origin)
    kana=list(kana)
    num1=len(origin)
    num2=len(kana)
    okurigana=""
    if origin[num1-1] == kana[num2-1] and origin[num1-2] == kana[num2-2] :
        okurigana=origin[num1-2]+origin[num1-1]
        origin[num1-1]=""
        origin[num1-2]=""
        kana[num2-1]=""
        kana[num2-2]=""
        origin,kana=tohensu(origin,kana)
    elif origin[num1-1] == kana[num2-1] :
        okurigana=origin[num1-1]
        origin[num1-1]=""
        kana[num2-1]=""
        origin="".join(origin)
        kana="".join(kana)
    else :
        origin,kana=tohensu(origin,kana)
    return origin,kana,okurigana
mecab = MeCab.Tagger("-Ochasen")
mecab.parse('')#空でパースする必要がある
node=mecab.parseToNode("私は大学を辞めたい")
while node :
    origin=node.surface#もとの単語を代入
    yomi=node.feature.split(",")[7]#読み仮名を代入
    kana=henkan(yomi)
    #正規表現で漢字と一致するかをチェック
    pattern = "[一-龥]"
    matchOB = re.match(pattern , origin)
    #originが空のとき、漢字以外の時はふりがなを振る必要がないのでそのまま出力する
    if origin != "" and matchOB:
        origin,kana,okurigana=kanadelete(origin,kana)
        print("<ruby><rb>{0}</rb><rt>{1}</rt></ruby>".format(origin,kana),end="")
        print(okurigana)
    else :
        print(origin)
    node=node.next

まとめ

今回は使用するコードの紹介に留め、次回から適正にルビが振られるようにコードを改修していこうと思う。ちなみにまだ終わりは見えていない。