[PYTHON] Ich habe einen japanischen Parser auf Japanisch mit Pyparsing geschrieben.

Überblick

Mit dem Pyparsing der Python-Bibliothek können Sie Grammatiken definieren, die einfach zu lesen und mit einem Bulletin für hierarchische Definitionen zu ändern sind. Ich bemerkte, dass es ohne Verwendung von if-Anweisungen beschrieben werden kann, und schrieb die Grammatik mit Japanisch, um Klassen, Methoden und Variablennamen zu pyparsen. Im Vergleich zur englischen Beschreibung mit dem gleichen Inhalt hatte ich das Gefühl, dass der Code auf Japanisch auf den ersten Blick leichter zu verstehen war. Es mag übertrieben sein, Klassen und Methoden ins Japanische zu übersetzen, aber ich hätte nicht gedacht, dass ich dies mit Japanisch in Python tun könnte. Verwendet Python 3.7, Pyparsing 2.4.6. (Anaconda-Verteilung)

Beschreibung und Ausführungsbeispiel

Unter der Annahme von drei Arten von Mitgliederlisten der Organisation habe ich die Grammatik des Parsers definiert, der sie auf Japanisch liest. Kanji wird für andere Variablennamen (Grammatikname, Ausdrucksname) als Python-reservierte Wörter, Funktionsnamen, importierte Klassennamen und Funktionsnamen sowie Analyseziele verwendet. Der Code ist ein Bottom-Up-Stapel von Sätzen von oben nach unten. Es ist ersichtlich, dass der Ausdruck auf der rechten Seite des folgenden am Ende beschriebenen Satzes die Grammatik der obersten Ebene ist und es drei Arten von Mitgliedern der Organisation gibt.

Verbandsmitglied=Unterstützendes Mitglied|Studentisches Mitglied|Einzelmitglied

Ich habe von unten nach oben geschrieben, aber beim Schreiben habe ich zuerst diese letzte Definition festgelegt, dann die untere Definition, die dem Teil entspricht, und dann die Methode, diesen letzten Satz in Details zu zerlegen. Definieren Sie einen Ausdruck, der mit dem ersten Token jeder Zeile im Dienstplan übereinstimmt, um die drei wichtigsten Arten von Mitgliedern zu verzweigen. Mit anderen Worten, die erste Übereinstimmung der zu analysierenden Zeichenfolge verzweigt sich je nach Firmenname oder Schulname. Einzelne Mitglieder sind anders. (Extrahieren Sie den Code unten)

Name der Firma=Rückwärtsspiel('Unternehmen')
Unterstützendes Mitglied= (Name der Firma+Vertreter+Mitgliedsnummer)('Unterstützendes Mitglied')

Schulname=Rückwärtsspiel('Universität') |Rückwärtsspiel('Technische Universität') |Rückwärtsspiel('Universität校')
Studentisches Mitglied= (Schulname+Vor-und Nachname+Vor- und Nachname lesen+Mitgliedsnummer)('Studentisches Mitglied')

Wie bei 〇✖ Co., Ltd. wird auch die Zuordnung von Firmenname und Schulname unter der Annahme fortlaufender Zeichenfolgen ohne Trennzeichen durch Suffixabgleich von regulären Ausdrücken wie oben beschrieben durchgeführt. Zuerst habe ich über die folgende Beschreibung nachgedacht, aber sie hat aufgrund des sogenannten gierigen Problems nicht funktioniert, bei dem der vorhergehende Ausdruck, die Kanji-Zeichenfolge (Word), beispielsweise von 'Co., Ltd.' gegessen wurde. Ich habe auch das längste Match versucht, aber es hat nicht funktioniert. Beim Pyparsing werden Token von links verbraucht, sodass die Präfixübereinstimmung kein Problem darstellt.

"""Nach dem Spiel treten Probleme mit übermäßigem Essen auf"""
Name der Firma=Beitreten(Kanji-String+ oneOf('GK Co., Ltd.'))('Name der Firma')
"""Das Präfix verursacht keine Probleme mit übermäßigem Essen"""
Name der Firma=Beitreten('Co., Ltd.' +Kanji-String)

Um das Format einer Liste von Sätzen mit regulären Ausdrücken beizubehalten, wird eine Funktion (Lambda-Ausdruck) bereitgestellt, die ein Suffix Regex zurückgibt. Es ist effizienter, die Suffix-Matching-Funktion so zu definieren, dass mehrere Zeichenfolgen übergeben werden können, z. B. "Godo Kaisha Co., Ltd.". In dieser Form werden jedoch mehrere Zeichen in der Grammatikbeschreibung mit einem einzigen Argument beschrieben. Wenn Sie die Grammatik mit Pyparsing definieren, können Sie zusätzlich zur Problemumgehung mit regulären Ausdrücken den Verbrauch stoppen, indem Sie den Zeichentyp der Eingabe vor und nach dem Einfügen eines Trennzeichens usw. ändern, um das zuvor erwähnte Problem des übermäßigen Essens zu vermeiden. .. In der symptomatischen Therapie nimmt die Lösung des Problems viel Zeit in Anspruch. (Eigentlich habe ich zwei Tage verschwendet, wenn es nicht so war) greedyeater.jpg

Nachfolgend finden Sie den gesamten Code mit den im Hauptteil angegebenen und getesteten Daten, einschließlich der einfachen Ausnahmebehandlung. Es scheint jedoch, dass pe.loc den ersten Fehlerort nicht immer korrekt angibt, wahrscheinlich aufgrund des Backtracks. Zuerst können Sie einige Grammatikbeschreibungen schreiben, aber wenn Sie einige schreiben, werden Sie den Dreh raus bekommen. Im Bild wird die zu analysierende Zeichenfolge in den in der Grammatik geschriebenen Code eingefügt, und nur diejenigen, die mit einem Ausdruck übereinstimmen, werden herausgefiltert.

parse_OrgMemberRecordReg.py


#by T.Hayashi
#tested with Python3.7, pyparsing 2.4.6
#don't use full-width space as delimitter in this script.
from pyparsing import (
Kombinieren als kombinieren,
Wort als Spalte,
Zahlen als Zahlen,
       __version__als Version,
       Regex ,
       pyparsing_unicode as uni,
       ParseException)

#Die folgenden Japaner
def Grammatik definieren():

Rückwärtsspiel= lambda s : Regex(r'.*'+s)
    
ganze Zahl=Säule(Zahlen)
Kanji-String=Säule(uni.Japanese.Kanji.alphas)
Kana Linie=Säule(uni.Japanese.Hiragana.alphas)

Mitgliedsnummer=ganze Zahl('Mitgliedsnummer')
    
Vor-und Nachname=Kanji-String('Vor-und Nachname')
Vor- und Nachname lesen=Kana Linie('Vor- und Nachname lesen')
    
Name der Firma=Beitreten('Co., Ltd.' +Kanji-String)
Name der Firma=Name der Firma|Rückwärtsspiel('Unternehmen')
Vertreter=Kanji-String('Vertreter')
Unterstützendes Mitglied= (Name der Firma+Vertreter+Mitgliedsnummer)('Unterstützendes Mitglied')

Schulname=Rückwärtsspiel('Universität') |Rückwärtsspiel('Technische Universität') |Rückwärtsspiel('Universität校')
Studentisches Mitglied= (Schulname+Vor-und Nachname+Vor- und Nachname lesen+Mitgliedsnummer)('Studentisches Mitglied')

Einzelmitglied= (Vor-und Nachname+Vor- und Nachname lesen+Mitgliedsnummer)('Einzelmitglied')
    
Verbandsmitglied=Unterstützendes Mitglied|Studentisches Mitglied|Einzelmitglied
Mitglied der Vereinigung zurückgeben

def test(gram,instr):
    try:
        r=gram.parseString(instr)
        name=r.getName()
        print(name,r.get(name))
        print()
    except ParseException as pe:
        print(f'error at {pe.loc} of {instr}')
        print(instr)
        #loc : char position.
        print(' '*(pe.loc-2)+'^')
        #print('Explain:\n',ParseException.explain(pe))


print('Pyparsing-Version:',Versionsnummer)       
Grammatik=Grammatikを定義()

Prüfung(Grammatik,'Taro Yamada Yamada Taro 3456')
Prüfung(Grammatik,'Fiktive Ostuniversität Saburo Kawasaki Kawasaki Saburo 5127')
Prüfung(Grammatik,'Fictitious Trading Co., Ltd. Totaro 0015') #Präfixübereinstimmung
Prüfung(Grammatik,'Fictitious Trading Co., Ltd. Taro Kaiyama 0010') #Rückwärtsspiel
Prüfung(Grammatik,'Nord-Nordwest-Nationales College für Technologie Ichiro Ito Ichiro Ito 900')
#Fehlerbestätigung Die High School ist nicht in der Definition enthalten
Prüfung(Grammatik,'Kita Tohoku Gymnasium Suzuki Saburo Suzuki Saburo 1000')
#Fehlerbestätigung: Das Unternehmen fehlt
Prüfung(Grammatik,'Stock Fictitious Trading Totaro 0015')
#Bestätigung des Fehlers Kanji zum Lesen
Prüfung(Grammatik,'Ichitaro Yamada Ichitaro Yamada 3456')

Das Folgende ist das Ausführungsergebnis.

Pyparsing-Version: 2.4.6
Einzelmitglied['Yamada Taro', 'Yamada Taro', '3456']

Studentisches Mitglied['Fiktive East University', 'Saburo Kawasaki', 'Kawasaki Saburo', '5127']

Unterstützendes Mitglied['Fictitious Trading Co., Ltd.', 'Totaro', '0015']

Unterstützendes Mitglied['Fictitious Trading Co., Ltd.', 'Taro Umiyama', '0010']

Studentisches Mitglied['Nord-Nordwest-Fachhochschule', 'Ichiro Ito', 'Ichirou Ito', '900']

Fehler bei 6 der Kita Tohoku High School Suzuki Saburo Suzuki Saburo 1000
Kita Tohoku Gymnasium Suzuki Saburo Suzuki Saburo 1000
    ^
Fehler bei 7 von Stock Fictitious Trading Totaro 0015
Stock Fictitious Trading Totaro 0015
     ^
Fehler bei 9 von Ichitaro Yamada Ichitaro Yamada 3456
Ichitaro Yamada Ichitaro Yamada 3456
       ^

Am Ende

Mit einer Liste von BNF-ähnlichen Definitionen (Backus-Naur-Form) konnte ich eine Grammatik definieren, die leichter zu verstehen ist als ein normales Programm. Ich dachte, wenn ich Japanisch verwenden würde, würden verschiedene unerwartete Dinge passieren, aber ohne das war ich überrascht, dass Python so viel kann. Ich habe darauf geachtet, das Problem des übermäßigen Essens nicht zu verursachen und zu vermeiden, dass bei der Eingabe des Codes unsichtbare Leerzeichen in voller Breite eingegeben werden. Das Definieren und Debuggen größerer Grammatiken, um korrekt zu funktionieren, kann schwierig zu verfolgen sein und ist möglicherweise nicht so einfach wie ein normales Python-Programm, je nachdem, wie Sie sie schreiben. Aus diesem Grund ist es bei einem Schüler, der wiederholt Ausnahmen und unerwartetes Verhalten macht und korrigiert, im Vergleich zu einem normalen Programm unbedingt erforderlich, von Anfang an so viel wie möglich den richtigen Code zu schreiben. .. .. Hinweis: Ich habe es das Problem des übermäßigen Essens genannt, aber es ist kein allgemeiner Begriff, und ich habe es hier vorläufig benannt.

Recommended Posts

Ich habe einen japanischen Parser auf Japanisch mit Pyparsing geschrieben.
Ich habe Python auf Japanisch geschrieben
Ein Memo, das ich schnell in Python geschrieben habe
Ich habe eine Klasse in Python3 und Java geschrieben
Ich habe ein Designmuster in der Kotlin Prototype Edition geschrieben
Ich habe FizzBuzz in Python mit der Support Vector Machine (Bibliothek LIVSVM) geschrieben.
Ich habe ein Designmuster in der Kotlin Factory Edition geschrieben
Ich habe ein Designmuster in der Kotlin Builder Edition geschrieben
Ich habe ein Designmuster in der Kotlin Singleton Edition geschrieben
Ich habe ein Designmuster in der Kotlin Adapter Edition geschrieben
Ich habe ein Designmuster in Kotlin geschrieben, das von Iterator bearbeitet wurde
Ich habe ein Designmuster in der Kotlin Template Edition geschrieben
Ich verstehe Python auf Japanisch!
Ich habe einen schnellen Feed-Reader mit Feedparser in Python erstellt
Ich habe ein Skript geschrieben, um eine beliebte Seite in Japan zu bekommen
Ich habe ein Skript geschrieben, das das Bild in zwei Teile teilt
Ich habe mit LightGBM einen Code geschrieben, der die Wiederherstellungsrate von 100% bei der Vorhersage von Pferderennen überschreitet (Teil 2).
Ich habe einen Line-Bot mit Python gemacht!
Ich erhalte einen KeyError in pyclustering.xmeans
Ich habe Fizz Buzz in Python geschrieben
Ich habe Gray Scale mit Pytorch geschrieben
Ich habe die Warteschlange in Python geschrieben
Ich habe den Stack in Python geschrieben
Ich habe eine Funktion zum Laden des Git-Erweiterungsskripts in Python geschrieben
Ich habe ein Skript geschrieben, um Webseiten-Links in Python zu extrahieren
[Python] Ich habe eine REST-API mit AWS API Gateway und Lambda geschrieben.
Ich habe einen Code geschrieben, um die Quaternion mit Python in einen Ölerwinkel vom Typ z-y-x umzuwandeln
Ich möchte in der Einschlussnotation drucken
Ich habe ein Pay-Management-Programm in Python erstellt!
Ich habe versucht, ○ ✕ mit TensorFlow zu spielen
Anfänger: Ich habe einen Launcher mit dem Wörterbuch erstellt
Schriftliche Auswahlsortierung in C.
Scraping von Websites mit JavaScript in Python
[Python] Ich habe gewaltsam eine kurze Funktion zur Erzeugung von Parlin-Geräuschen in Numpy geschrieben.
Zeichnen Sie mit graphviz eine Baumstruktur in Python 3
Ich habe Project Euler 1 in einem Liner geschrieben.
Ich habe versucht, pipenv zu verwenden, machen Sie sich also eine Notiz
Startete Node.js in einer virtuellen Umgebung
Ich habe ein Passwort-Tool in Python erstellt.
Ich habe den Gleitflügel in der Schöpfung geschrieben.
Ich habe ein Diagramm wie R glmnet in Python für die spärliche Modellierung mit Lasso geschrieben
[Basic Information Engineer Examination] Ich habe einen linearen Suchalgorithmus in Python geschrieben.
Ich habe ein PyPI-Modul geschrieben, das den Parameterstil in Pythons sqlite3-Modul erweitert
Erstellen Sie eine GIF-Datei mit Pillow in Python
Wenn ich einen Chrom-Treiberfehler in Selenium bekomme
Zeichnen Sie in Jupyter ein Diagramm mit japanischen Beschriftungen
Ich möchte mit Python ein Fenster erstellen
Ich habe versucht, mit Python ein Tippspiel zu spielen
Erstellen Sie mit Kaitai Struct einen Binärdatenparser
Anzeigen von Arzneimittelbewertungen mithilfe von Listen in Python
Ich habe versucht, Pythonect, eine Programmiersprache für den Datenfluss, zu verwenden.
Ich habe versucht, eine CSV-Datei mit Python zu lesen
Ich habe versucht, ein Python 3-Modul in C hinzuzufügen
[PyTorch] Ich war ein wenig verloren in torch.max ()
Tipps für eine gute Verwendung von Elastic Search
Erstellen Sie eine MIDI-Datei in Python mit pretty_midi
Zeichnen Sie YouTube-Aufrufe mit Lambda in einer Tabelle auf
Ich habe versucht, die Datenbank (sqlite3) mit kivy zu verwenden
Ich habe ein Caesar-Kryptografieprogramm in Python erstellt.
Ich habe ein ○ ✕ Spiel mit TensorFlow gemacht