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)
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)
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
^
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