Erstellen Sie mit Mecab aus Python3 ein Tool, das Furigana automatisch mit HTML schüttelt

2019.3.25 Nachtrag

Das in diesem Artikel vorgestellte Programm kann die beschriebenen Beispielsätze bis zu einem gewissen Grad verarbeiten, aber ich habe festgestellt, dass einige Wörter nicht richtig schwingen.

Auf der folgenden Website wird eine bessere Version des Codes in diesem Artikel vorgestellt. Schauen Sie also bitte mal rein! https://www.karelie.net/python3-mecab-html-furigana-1/

Wir möchten Kimera dafür danken, dass sie auf die Probleme in diesem Artikel hingewiesen hat.

Was du tun kannst

Ich möchte das College verlassen

Automatisch, wenn es HTML gibt

<ruby><rb>ich</rb><rt>ich</rt></ruby>Ist
<ruby><rb>Universität</rb><rt>Toll</rt></ruby>Zu
<ruby><rb>Rücktritt</rb><rt>Oder</rt></ruby>Metai

I </ rb> I </ rt> </ ruby> Universität </ rb> Daigaku </ rt> </ ruby> Bemerkungen </ rb> und </ rt> </ ruby>

Und Rubin wird sich berühren

Dinge notwendig

Die Umgebung ist MacOS und die Python-Version ist 3.5.1. 1.Mecab (In meinem Fall war es standardmäßig in Mac enthalten, daher werde ich es weglassen.) 2.mecab-python3 3.pip (erforderlich, um mecab-python3 zu installieren)

Nimm was du brauchst

Mecab ist ein Tool zur Wörterbuchanalyse, mit dem Sie Kanji lesen können.

Sie können es ausführen / abrufen, indem Sie den Befehl mecab über die Befehlszeile ausführen und den Text in die nächste Zeile eingeben.

$ mecab
Ich möchte das College verlassen
Mein Substantiv,Gleichbedeutend,Allgemeines,*,*,*,ich,ich,ich
Ist ein Assistent,Hilfe,*,*,*,*,Ist,C.,Beeindruckend
Universitätsnomenklatur,Allgemeines,*,*,*,*,Universität,Daigaku,Daigaku
Hilfs,Fallassistent,Allgemeines,*,*,*,Zu,Wo,Wo
Verb beenden,Unabhängigkeit,*,*,Ein Schritt,Kontinuierlicher Typ,Verlassen,Yame,Yame
Tai Assistent Verb,*,*,*,Spezielles Thailand,Grundform,Wollen,Thailand,Thailand
EOS

Um dieses Mecab mit Python3 zu verarbeiten, ist ein Paket namens Python-Mecab3 erforderlich.

Weil das Tool zum Verwalten solcher Pakete pip heißt Wenn pip nicht installiert ist, installieren Sie es zuerst. (Ähnlich einem Edelstein in Ruby)

Rohrinstallation

$ easy_install pip

Übrigens scheint es standardmäßig in Python3.4 enthalten zu sein.

installiere mecab-python3

Installieren Sie nach der Installation von pip mecab-python3.

$ pip install mecab-python3

Mit dem Befehl pip list können Sie eine Liste der aktuell enthaltenen Pakete abrufen. Wenn Sie Mecab-Python haben, ist die Installation erfolgreich.

$ pip list
mecab-python3 (0.7)

Lassen Sie uns Mecab vorerst mit Python3 behandeln

Nachdem die Umgebung vorerst bereit ist, versuchen wir, Mecab von Python zu verwenden und zu sehen, wie wir die Daten erhalten können.

macab.py


#!/usr/local/src/pyenv/shims/python
# -*- coding: utf_8 -*-
import sys
import MeCab

mecab = MeCab.Tagger("-Ochasen")#Rufen Sie Mecab an
text=mecab.parse('Ich möchte das College verlassen')#Holen Sie sich Furigana

print(text)
$ mecab.py
Ich bin meine Nomenklatur-Gleichbedeutend-Allgemeines
Ha ha ist ein Assistent-Hilfe
Universität Daigaku University Nomen-Allgemeines
Wo wo Auxiliary-Fallassistent-Allgemeines
Beenden Sie das Verb-Unabhängiger einstufiger Dauereinsatz
Tai Tai Tai Tai Hilfsverb Spezial / Thailändische Grundform
EOS

Parse scheint "Analyse" zu bedeuten

mecab = MeCab.Tagger("-Ochasen")

Nach dem Anruf bei Mecab mit

text=mecab.parse('Ich möchte das College verlassen')

Sie können es in einem Format wie dem Ausführungsergebnis abrufen, indem Sie die Analysemethode aufrufen und den zu analysierenden Text in seinem Argument angeben.

Verwenden Sie parseToNode

Ich konnte es vorerst bekommen, aber dieses Format ist sehr schwierig programmgesteuert zu handhaben, da es durch Leerzeichen getrennt ist.

Ändern Sie es daher in ein Format namens "Knoten", um die Handhabung zu vereinfachen.

mecab.py


import sys
import MeCab


mecab = MeCab.Tagger("-Ochasen")
mecab.parse('')#Müssen am Himmel analysieren
node=mecab.parseToNode('Ich möchte das College verlassen')

while node :
    print(node.surface+"\t"+node.feature)
    node=node.next
$ mecab.py
	BOS/EOS,*,*,*,*,*,*,*,*
Mein Substantiv,Gleichbedeutend,Allgemeines,*,*,*,ich,ich,ich
Ist ein Assistent,Hilfe,*,*,*,*,Ist,C.,Beeindruckend
Universitätsnomenklatur,Allgemeines,*,*,*,*,Universität,Daigaku,Daigaku
Hilfs,Fallassistent,Allgemeines,*,*,*,Zu,Wo,Wo
Verb beenden,Unabhängigkeit,*,*,Ein Schritt,Kontinuierlicher Typ,Verlassen,Yame,Yame
Tai Assistent Verb,*,*,*,Spezielles Thailand,Grundform,Wollen,Thailand,Thailand
	BOS/EOS,*,*,*,*,*,*,*,*

Dies erleichtert die Handhabung, da die Analyseergebnisse getrennt durch "," erhalten werden können.

Wenn Sie Mecab aufrufen, müssen Sie das Argument nach wie vor leeren und vorerst analysieren. Tun Sie dies also.

danach

node=mecab.parseToNode('Ich möchte das College verlassen')

Geben Sie einen Satz im Argument der parseToNode-Methode an.

Da der Knoten Wort für Wort verarbeitet wird, verwenden Sie die while-Anweisung. Schleife bis zum Ende des Satzes (Ende des Wertes im Knoten).

In der Schleife Der Text des ursprünglichen Arguments in node.surface, Mit node.feature können Sie durch Kommas getrennte Analysedaten abrufen.

Apropos

  node=node.next

Wenn Sie es vergessen, wird es eine Endlosschleife geben, seien Sie also vorsichtig.

Bisher ist es mir vorerst gelungen, Mecab aus Python zu verwenden.

Schütteln Sie den Rubin tatsächlich im HTML-Format

Bisher gab es viele Informationen im Internet, Von hier an gibt es nicht mehr viele Informationen und es ist ein schwieriger Teil.

Grundsätzlich ist es jedoch eine Arbeit, auf HTML anzuwenden, während Sie mit der obigen node.feature spielen.

Wie man Rubin in HTML schwingt

<ruby><rb>Brief</rb><rt>Moji</rt></ruby>

Zeichen </ rb> moji </ rt> </ ruby>

Weil es in Form von sein wird Wenden wir das ursprüngliche Kanji im -Tag und das Furigana im rt-Tag an.

mecab.py


#!/usr/local/src/pyenv/shims/python
# -*- coding: utf_8 -*-

import sys
import MeCab
import re

mecab = MeCab.Tagger("-Ochasen")
mecab.parse('')#Müssen am Himmel analysieren
node=mecab.parseToNode('Ich möchte das College verlassen')

while node :
    origin=node.surface#Ersetzen Sie das ursprüngliche Wort
    kana=node.feature.split(",")[7]#Ersetzen Sie das Lesen von Kana

    #Überprüfen Sie, ob der reguläre Ausdruck mit dem Kanji übereinstimmt
    pattern = "[einer-龥]"
    matchOB = re.match(pattern , origin)

    #Wenn der Ursprung leer ist, muss das Furigana nicht geschüttelt werden, wenn es kein Kanji ist. Daher wird es so ausgegeben, wie es ist
    if origin != "" and matchOB:
        print("<ruby><rb>{0}</rb><rt>{1}</rt></ruby>".format(origin,kana),end="")
    else :
        print(origin)

    node=node.next

$ mecab.py
<ruby><rb>ich</rb><rt>ich</rt></ruby>Ist
<ruby><rb>Universität</rb><rt>Daigaku</rt></ruby>Zu
<ruby><rb>Verlassen</rb><rt>Yame</rt></ruby>Wollen

I </ rb> I </ rt> </ ruby> Universität </ rb> Daigaku </ rt> </ ruby> ruby> Beende </ rb> Yame </ rt> </ ruby>

Es wird immer mehr so.

Weisen Sie in den ersten beiden Zeilen zunächst dem Ursprung bzw. dem Kana Wörter und Messwerte zu.

In Bezug auf das Yomigana gibt die Split-Funktion das 7. durch Kommas getrennte Array an, da das Yomigana der 7. durch Kommas getrennte Knoten ist.

origin=node.surface #Ersetzen Sie das ursprüngliche Wort
kana=node.feature.split(",")[7] #Ersetzen Sie das Lesen von Kana

Als nächstes möchte ich diesmal nur dann vorgeben, Furigana zu sein, wenn das ursprüngliche Wort Kanji ist Verwenden Sie reguläre Ausdrücke, um zu überprüfen, ob das ursprüngliche Wort ein Kanji ist.

Um einen regulären Ausdruck zu verwenden, importieren Sie zunächst re am Anfang.

import re

Ich werde hier nicht näher auf reguläre Ausdrücke eingehen. Es gibt verschiedene Methoden für die früher wieder importierte.

Dieses Mal möchte ich herausfinden, ob das erste Zeichen des Wortursprungs ein Kanji ist Verwenden Sie die Match-Methode. Geben Sie im ersten Argument ein Muster (diesmal Kanji) und im zweiten Argument ein Wort an.

Wenn eine Übereinstimmung vorliegt, werden Informationen zu der Übereinstimmung gespeichert, die als Übereinstimmungsobjekt bezeichnet wird. Wenn keine Übereinstimmung vorliegt, wird "Keine" gespeichert.

  #Überprüfen Sie, ob der reguläre Ausdruck mit dem Kanji übereinstimmt
    pattern = "[einer-龥]" #Kanji-Muster
    matchOB = re.match(pattern , origin) #Keine, wenn nicht in Kanji

Schließlich, wenn für die Beurteilung verwendet wird.

Wenn Sie es auf Japanisch organisieren ・ Wenn der Ursprung Kanji ist ➡ Rubin mit HTML schütteln und ausgeben ・ Wenn der Ursprung nicht Kanji ist (Hiragana, Katakana, Number usw.) ➡ Ausgabe so wie sie ist Es wird sein.

  #Wenn der Ursprung leer ist, muss das Furigana nicht geschüttelt werden, wenn es kein Kanji ist. Daher wird es so ausgegeben, wie es ist
    if matchOB and origin != "" :
        print("<ruby><rb>{0}</rb><rt>{1}</rt></ruby>".format(origin,kana),end="")
    else :
        print(origin)

Wenn der Ursprung nicht Kanji ist, wird none MarchOB zugewiesen, sodass er beurteilt wird und sich zu einem anderen verschiebt.

Bis zu diesem Punkt ist es eine ziemliche Form geworden, aber es gibt ein Problem.

Katakana-Problem

Ich möchte das sendende Kana mit Hiragana schwingen, aber das lesende Kana, das mit Mecab erhalten werden kann, ist Katakana, also möchte ich dies in Hiragana umwandeln.

In Ruby können Sie dies mit einer Funktion auf einmal tun, aber soweit ich mit Python überprüft habe, scheint es, dass dies nicht möglich ist.

Deshalb werde ich hier etwas erfinden.

Bereiten Sie zunächst eine Reihe solcher Hiragana- und Katakana-Charaktere nacheinander vor.

hiragana=["Ah","ich","U.","Hmm"]#hiragana[0]=="Ah"
katakana=["EIN,"ich","C.","Nieder"]#katakana[0]=="EIN"

Und zum Beispiel Angenommen, Sie möchten das Wort "ai" in "ai" ändern.

text=list("Auge")#text[0]=="EIN" text[1]=="ich"werden
kana=""#Variable, um Hiragana zu setzen

for hoge in len(text)#Wiederholen Sie diesen Vorgang für die Anzahl der Zeichen(Ersatz für hoge)
  for i in list(katakana)
    katakana[i]==hoge
    kana+=hiragana[i]

print(kana)#Ai

Ich möchte "Ai" in A und I teilen und sie einzeln zusammenstellen. Teilen Sie das "Auge" Zeichen für Zeichen in ein Array.

Schleifen Sie dann die Nummer des Arrays (= Anzahl der Zeichen).

Darin Schleife um die Anzahl der Katakana und Match mit Hoge. Da der Inhalt des Hoges der ersten Schleife diesmal "A" ist Wenn i 0 ist, stimmt es mit katakana [0] überein.

Schließlich Hiragana [i], dh Hiragana [0], dh "a" Zur Variablen kana.

Wenn Sie dies für die Anzahl der Zeichen wiederholen, hat Kana Hiragana.

Hier ist der Code, der dies modularisiert.

mecab.py


#!/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=""
    #Hiragana mit Kata Kana von Yomikana
    for text in list(text):
        for i in range(83):
            if text == katakana[i]:
                kana+=hiragana[i]
    return kana

mecab = MeCab.Tagger("-Ochasen")
mecab.parse('')#Müssen am Himmel analysieren
node=mecab.parseToNode('Ich möchte das College verlassen')

while node :
    origin=node.surface#Ersetzen Sie das ursprüngliche Wort
    kana=node.feature.split(",")[7]#Ersetzen Sie das Lesen von Kana
    kana=henkan(kana)#Rufen Sie die Konvertierungsfunktion auf und verwandeln Sie Katakana in Hiragana

    #Überprüfen Sie, ob der reguläre Ausdruck mit dem Kanji übereinstimmt
    pattern = "[einer-龥]"
    matchOB = re.match(pattern , origin)

    #Wenn der Ursprung leer ist, muss das Furigana nicht geschüttelt werden, wenn es kein Kanji ist. Daher wird es so ausgegeben, wie es ist
    if origin != "" and matchOB:
        print("<ruby><rb>{0}</rb><rt>{1}</rt></ruby>".format(origin,kana),end="")
      
    else :
        print(origin)

    node=node.next

Ich werde die Details weglassen,

range(83)

Dies liegt daran, dass die Anzahl der Arrangements 83 sowie 50 Sounds mit kleinen Buchstaben beträgt.

Senden eines Pseudonymproblems

Ein weiteres Problem ist das Problem des Sendens von Pseudonymen. Da Mecab durch ein Wort getrennt ist, enthält es auch das sendende Pseudonym, was bedeutet, dass der Rubin nicht nur Kanji zugeordnet ist.

Mit anderen Worten

<ruby><rb>Verlassen</rb><rt>halt</rt></ruby>

Beenden Sie </ rb> Stop </ rt> </ ruby>

nicht

<ruby><rb>Rücktritt</rb><rt>Oder</rt></ruby>Mich

Diktieren Sie </ rb> und </ rt> </ ruby>

Ich möchte es tun.

Schauen wir uns das an.

Grundsätzlich wird bestimmt, ob das ursprüngliche Wort und das Ende des sendenden Pseudonyms übereinstimmen.

Herkunft: Schönheit gut </ font> kana: Utsuku neu </ font> Ursprung: Führen Sie </ font> aus kana: Stäbchen ru </ font>

Da diese am Ende dieselben zwei oder einen Buchstaben haben, können sie als Pseudonyme gesendet werden.

Auch diesbezüglich, wie im Fall des Katakana-Problems früher Zerlegen Sie Herkunft und Kana Zeichen für Zeichen und ordnen Sie sie an Beurteilt, ob ein oder zwei Zeichen am Ende eines Wortes übereinstimmen.

mecab.py


#!/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=""
    #Hiragana mit Kata Kana von Yomikana
    for text in list(text):
        for i in range(83):
            if text == katakana[i]:
                kana+=hiragana[i]
    return kana


mecab = MeCab.Tagger("-Ochasen")
mecab.parse('')#Müssen am Himmel analysieren
node=mecab.parseToNode('Ich möchte das College verlassen')

while node :
    origin=node.surface#Ersetzen Sie das ursprüngliche Wort
    yomi=node.feature.split(",")[7]#Ersetzen Sie das Lesen von Kana
    kana=henkan(yomi)

    #Überprüfen Sie, ob der reguläre Ausdruck mit dem Kanji übereinstimmt
    pattern = "[einer-龥]"
    matchOB = re.match(pattern , origin)

    #Wenn der Ursprung leer ist, muss das Furigana nicht geschüttelt werden, wenn es kein Kanji ist. Daher wird es so ausgegeben, wie es ist
    if origin != "" and matchOB:

        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="".join(origin)
            kana="".join(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="".join(origin)
            kana="".join(kana)

        print("<ruby><rb>{0}</rb><rt>{1}</rt></ruby>".format(origin,kana),end="")
        print(okurigana)

    else :
        print(origin)

    node=node.next

Wenn Sie dies tun,

$ mecab.py
<ruby><rb>ich</rb><rt>ich</rt></ruby>
Ist
<ruby><rb>Universität</rb><rt>Toll</rt></ruby>
Zu
<ruby><rb>Rücktritt</rb><rt>Oder</rt></ruby>Mich
Wollen

I </ rb> I </ rt> </ ruby> Universität </ rb> Daigaku </ rt> </ ruby> Bemerkungen </ rb> und </ rt> </ ruby>

Und es ist vollbracht! !! !!

Lass uns genauer hinschauen.

origin=list(origin)
kana=list(kana)

num1=len(origin)
num2=len(kana)
 
okurigana=""

Zunächst habe ich, wie bereits erwähnt, jedes Zeichen überprüft, damit ich es mit der Listenfunktion anordnen kann.

Um zu überprüfen, ob die Endungen übereinstimmen, überprüfen Sie auch die Anzahl der Arrays mit der len-Funktion. Ersetzen Sie num1 bzw. num2.

  if origin[num1-1] == kana[num2-1] and origin[num1-2] == kana[num2-2] :
            okurigana=origin[num1-2]+origin[num1-1]

            origin[num1-1]=""
            kana[num1-2]=""
            origin[num2-1]=""
            kana[num2-2]=""

            origin="".join(origin)
            kana="".join(kana)

Dies ist die Verarbeitung, wenn das letzte Zeichen und das vorletzte übereinstimmen, d. H. Dies ist der Prozess für Wörter wie "schön".

In diesem Fall sind die letzten beiden Zeichen "shii" das sendende Pseudonym Weisen Sie dies der Variablen okurigana zu.

okurigana=origin[num1-2]+origin[num1-1]

Sobald Sie es in eine Variable eingefügt haben, benötigen Sie kein "Shii" mehr. Löschen Sie es also.

origin[num1-1]=""
kana[num1-2]=""
origin[num2-1]=""
kana[num2-2]=""

Endlich links Herkunft = ["Schönheit"] kana = ["u", "tsu", "ku"] Verwenden Sie die Join-Funktion, um zu einer Variablen zurückzukehren.

origin="".join(origin)
kana="".join(kana)

Im Übrigen ist es vielleicht ein Ein-Buchstaben-Pseudonym wie "run" Es ist ein Prozess, bei dem es kein sendendes Pseudonym wie "Universität" gibt.

        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="".join(origin)
            kana="".join(kana)

Da es arrangiert wurde, auch wenn es keine Verarbeitung gibt und es kein sendendes Pseudonym gibt Arbeiten Sie, um zu einer Variablen zurückzukehren.

Der letzte wird ausgegeben.

Da es der Variablen bisher genau in der Verarbeitung zugewiesen wurde, gibt es keine besondere Änderung, aber da das sendende Pseudonym okurigana zugewiesen ist, ist es in Ordnung, wenn Sie nicht vergessen, dies auszugeben.

print("<ruby><rb>{0}</rb><rt>{1}</rt></ruby>".format(origin,kana),end="")
print(okurigana)

Der Rest ist ein wenig schwer zu sehen, also wenn Sie es zu einer Funktion machen, ist es erledigt!

mecab.py


#!/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=""
    #Hiragana mit Kata Kana von Yomikana
    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('')#Müssen am Himmel analysieren
node=mecab.parseToNode("Ich möchte das College verlassen")

while node :
    origin=node.surface#Ersetzen Sie das ursprüngliche Wort
    yomi=node.feature.split(",")[7]#Ersetzen Sie das Lesen von Kana
    kana=henkan(yomi)

    #Überprüfen Sie, ob der reguläre Ausdruck mit dem Kanji übereinstimmt
    pattern = "[einer-龥]"
    matchOB = re.match(pattern , origin)

    #Wenn der Ursprung leer ist, muss das Furigana nicht geschüttelt werden, wenn es kein Kanji ist. Daher wird es so ausgegeben, wie es ist
    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

Recommended Posts