Welche verschiedenen Methoden gibt es zum Parsen von Zeichenfolgen in Java?[geschlossen]

StackOverflow https://stackoverflow.com/questions/2968

  •  08-06-2019
  •  | 
  •  

Frage

Zum Parsen von Player-Befehlen habe ich am häufigsten verwendet Teilt Methode, um eine Zeichenfolge durch Trennzeichen aufzuteilen und dann den Rest einfach durch eine Reihe von herauszufinden ifs oder switches.Welche verschiedenen Möglichkeiten gibt es, Strings in Java zu analysieren?

War es hilfreich?

Lösung

Ich gehe davon aus, dass Sie versuchen, die Befehlsschnittstelle so fehlerverzeihend wie möglich zu gestalten.Wenn dies der Fall ist, empfehle ich Ihnen, einen ähnlichen Algorithmus zu verwenden:

  1. Lesen Sie die Zeichenfolge ein
    • Teilen Sie die Zeichenfolge in Token auf
    • Verwenden Sie ein Wörterbuch, um Synonyme in eine allgemeine Form umzuwandeln
    • Wandeln Sie beispielsweise „Hit“, „Punch“, „Strike“ und „Kick“ in „Hit“ um.
    • Führen Sie Aktionen auf einer ungeordneten, inklusiven Basis aus
    • Ungeordnet - „Dem Affen ins Gesicht schlagen“ ist dasselbe wie „dem Affen ins Gesicht schlagen“
    • Inklusive - Wenn der Befehl „Dem Affen ins Gesicht schlagen“ lauten soll und „Affen schlagen“ angeboten wird, sollten Sie prüfen, wie viele Befehle damit übereinstimmen.Wenn nur ein Befehl vorhanden ist, führen Sie diese Aktion aus.Es könnte sogar eine gute Idee sein, Befehlsprioritäten zu haben, und selbst wenn es überhaupt Übereinstimmungen gäbe, würde es die oberste Aktion ausführen.

Andere Tipps

Ich mag reguläre Ausdrücke sehr.Solange die Befehlszeichenfolgen relativ einfach sind, können Sie ein paar reguläre Ausdrücke schreiben, deren manuelle Analyse einige Seiten Code erfordern könnte.

Ich würde vorschlagen, dass Sie vorbeischauen http://www.regular-expressions.info für eine gute Einführung in reguläre Ausdrücke sowie spezifische Beispiele für Java.

Das manuelle Parsen macht viel Spaß ...am Anfang:)

Wenn Befehle nicht sehr anspruchsvoll sind, können Sie sie in der Praxis auf die gleiche Weise behandeln wie Befehle, die in Befehlszeileninterpretern verwendet werden.Es gibt eine Liste von Bibliotheken, die Sie verwenden können: http://java-source.net/open-source/command-line.Ich denke, Sie können damit beginnen Apache Commons-CLI oder args4j (verwendet Anmerkungen).Sie sind gut dokumentiert und wirklich einfach in der Anwendung.Sie übernehmen das Parsen automatisch und das Einzige, was Sie tun müssen, ist, bestimmte Felder in einem Objekt zu lesen.

Wenn Sie über anspruchsvollere Befehle verfügen, ist die Erstellung einer formalen Grammatik möglicherweise die bessere Idee.Es gibt eine sehr gute Bibliothek mit grafischem Editor, Debugger und Interpreter für Grammatiken.Es heißt ANTLR (und der Herausgeber ANTLRWorks) und es ist kostenlos:) Es gibt auch einige Beispielgrammatiken und Tutorials.

Ich würde es mir ansehen Java-Migrationen von Zork, und neigen Sie zu einem einfachen Prozessor für natürliche Sprache (gesteuert entweder durch Tokenisierung oder Regex) wie das Folgende (von diesem Link):

    public static boolean simpleNLP( String inputline, String keywords[])
    {
        int i;
        int maxToken = keywords.length;
        int to,from;
        if( inputline.length() = inputline.length()) return false; // check for blank and empty lines
        while( to >=0 )
        {
            to = inputline.indexOf(' ',from);
            if( to > 0){
                lexed.addElement(inputline.substring(from,to));
                from = to;
                while( inputline.charAt(from) == ' '
                && from = keywords.length) { status = true; break;}
            }
        }
        return status;
    }

...

Alles, was einem Programmierer einen Grund gibt, sich Zork noch einmal anzusehen, ist meiner Meinung nach gut, aber achten Sie nur auf Grues.

...

Sun selbst empfiehlt, sich von StringTokenizer fernzuhalten und stattdessen die Methode String.spilt zu verwenden.

Sie sollten sich auch die Pattern-Klasse ansehen.

Eine weitere Stimme für ANTLR/ANTLRWorks.Wenn Sie zwei Versionen der Datei erstellen, eine mit dem Java-Code zum tatsächlichen Ausführen der Befehle und eine ohne (nur mit der Grammatik), dann haben Sie eine ausführbare Spezifikation der Sprache, die sich hervorragend zum Testen eignet und ein Segen für die Dokumentation ist und eine große Zeitersparnis, falls Sie sich jemals für eine Portierung entscheiden.

Wenn es darum geht, Befehlszeilen zu analysieren, würde ich die Verwendung empfehlen Commons Cli.

Die Apache Commons CLI-Bibliothek stellt eine API zur Verarbeitung von Befehlszeilenschnittstellen bereit.

Versuchen JavaCC ein Parser-Generator für Java.

Es verfügt über viele Funktionen zum Interpretieren von Sprachen und wird von Eclipse gut unterstützt.

@CodingTheWheel Hier ist Ihr Code, ein wenig aufgeräumt und durch Eclipse (Strg+Schicht+F) und das hier wieder eingefügt :)

Einschließlich der vier Leerzeichen vor jeder Zeile.

public static boolean simpleNLP(String inputline, String keywords[]) {
    if (inputline.length() < 1)
        return false;

    List<String> lexed = new ArrayList<String>(); 
    for (String ele : inputline.split(" ")) {
        lexed.add(ele);
    }


    boolean status = false;
    to = 0;
    for (i = 0; i < lexed.size(); i++) {
        String s = (String) lexed.get(i);
        if (s.equalsIgnoreCase(keywords[to])) {
            to++;
            if (to >= keywords.length) {
                status = true;
                break;
            }
        }
    }
    return status;
}

Ein einfacher String-Tokenizer für Leerzeichen sollte funktionieren, aber es gibt wirklich viele Möglichkeiten, dies zu tun.

Hier ist ein Beispiel für die Verwendung eines Tokenizers:

String command = "kick person";
StringTokenizer tokens = new StringTokenizer(command);
String action = null;

if (tokens.hasMoreTokens()) {
    action = tokens.nextToken();
}

if (action != null) {
    doCommand(action, tokens);
}

Dann können Token weiter für die Argumente verwendet werden.Dies alles setzt voraus, dass in den Argumenten keine Leerzeichen verwendet werden ...Vielleicht möchten Sie also Ihren eigenen einfachen Parsing-Mechanismus entwickeln (z. B. das erste Leerzeichen abrufen und Text davor als Aktion verwenden oder einen regulären Ausdruck verwenden, wenn Ihnen der Geschwindigkeitsverlust nichts ausmacht), ihn einfach abstrahieren, damit er verwendet werden kann überall.

Wenn die Trennzeichenfolge für den Befehl immer dieselbe Zeichenfolge oder dasselbe Zeichen ist (wie „;“), empfehlen wir Ihnen die Verwendung der StrinkTokenizer-Klasse:

StringTokenizer

Wenn das Trennzeichen jedoch variiert oder komplex ist, empfehlen wir Ihnen, die regulären Ausdrücke zu verwenden, die seit 1.4 von der String-Klasse selbst, Methode Split, verwendet werden können.Es verwendet die Pattern-Klasse aus dem Paket java.util.regex

Muster

Wenn die Sprache so einfach ist wie gerade

VERB NOMEN

dann funktioniert das Teilen von Hand gut.

Wenn es komplexer ist, sollten Sie sich unbedingt ein Tool wie ANTLR oder JavaCC ansehen.

Ich habe ein Tutorial zu ANTLR (v2) unter http://javadude.com/articles/antlrtut So erhalten Sie eine Vorstellung davon, wie es funktioniert.

JCommander Scheint ziemlich gut zu sein, obwohl ich es noch nicht getestet habe.

Wenn Ihr Text einige Trennzeichen enthält, können Sie Ihre split Methode.
Wenn der Text unregelmäßige Zeichenfolgen enthält, müssen Sie ein anderes Format verwenden regular expressions.

Die Split-Methode kann einen String in ein Array des angegebenen Teilstring-Ausdrucks aufteilen regex.Seine Argumente in zwei Formen, nämlich:Teilt (String regex) und teilen (String regex, int limit), die aufgeteilt (String regex) wird tatsächlich durch Aufrufen von split (String regex, int limit) erreicht, Grenze ist 0.Dann, wenn die Grenze > 0 Und Grenze <0 stellt was dar?

Wenn das jdk erklärt:Wann Grenze > 0 Sub-Array-Längen sind bis zu einer Grenze, d. h. wenn möglich, möglich limit-1 Unterteilung, die als Teilzeichenfolge verbleibt (außer bei maximal 1 Mal, wenn das Zeichen ein Zeichen mit geteilter Zeichenfolge hat);

Grenze <0 gibt an, dass die Länge des Arrays nicht begrenzt ist.

Grenze = 0 Am Ende der Zeichenfolge wird eine leere Zeichenfolge abgeschnitten.StringTokenizer Die Klasse dient aus Kompatibilitätsgründen und ist eine beibehaltene Legacy-Klasse. Daher sollten wir versuchen, die Split-Methode der String-Klasse zu verwenden.beziehen auf Verknüpfung

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top