Welche unterschiedlichen Methoden gibt es, um Zeichenfolgen in Java zu analysieren?

Translate

Zum Parsen von Player-Befehlen habe ich am häufigsten die verwendetTeiltMethode, um einen String durch Trennzeichen zu teilen und dann den Rest durch eine Reihe von Trennzeichen herauszufindenifs oderswitches. Welche verschiedenen Möglichkeiten gibt es, Zeichenfolgen in Java zu analysieren?

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

Ich gehe davon aus, dass Sie versuchen, die Befehlsoberfläche so fehlerverzeihend wie möglich zu gestalten. In diesem Fall empfehlen wir Ihnen, einen ähnlichen Algorithmus zu verwenden:

  1. Read in the string
    • Teilen Sie die Zeichenfolge in Token auf
    • Verwenden Sie ein Wörterbuch, um Synonyme in eine gemeinsame Form zu konvertieren
    • Konvertieren Sie beispielsweise "Treffer", "Schlag", "Schlag" und "Tritt" in "Treffer".
    • Führen Sie Aktionen auf einer ungeordneten, inklusiven Basis aus
    • Ungeordnet- "Schlag dem Affen ins Gesicht" ist dasselbe wie "Das Gesicht im Affenschlag".
    • Inklusive- Wenn der Befehl "Schlag dem Affen ins Gesicht" lauten soll und "Schlagaffe" liefert, solltest du überprüfen, wie viele Befehle dies entspricht. Wenn nur ein Befehl ausgeführt wird, 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.
Quelle
Translate

Ich mag reguläre Ausdrücke sehr. Solange die Befehlszeichenfolgen recht einfach sind, können Sie einige reguläre Ausdrücke schreiben, für deren manuelles Parsen einige Seiten Code erforderlich sein können.

Ich würde vorschlagen, dass Sie auscheckenhttp://www.regular-expressions.infofür eine gute Einführung in Regexes sowie spezifische Beispiele für Java.

Quelle
Translate

Manuelles Parsen macht viel Spaß ... am Anfang :)

In der Praxis können Befehle, die nicht sehr ausgefeilt sind, genauso behandelt werden wie Befehle, die in Befehlszeileninterpreten 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 beginnenApache Commons CLIoderargs4j(verwendet Anmerkungen). Sie sind gut dokumentiert und sehr einfach zu bedienen. Sie verarbeiten das Parsen automatisch und das einzige, was Sie tun müssen, ist, bestimmte Felder in einem Objekt zu lesen.

Wenn Sie komplexere Befehle haben, ist es möglicherweise besser, eine formale Grammatik zu erstellen. Es gibt eine sehr gute Bibliothek mit grafischem Editor, Debugger und Interpreter für Grammatiken. Es heißtANTLR(und der HerausgeberANTLRWorks) und es ist kostenlos :) Es gibt auch einige Beispielgrammatiken und Tutorials.

Quelle
Myra Lee
Translate

Ich würde schauenJava-MigrationenvonZorkund beugen sich zu einem einfachenProzessor für natürliche Sprache(entweder durch Tokenisierung oder Regex gesteuert) wie die folgenden (über diesen 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 anzuschauen, ist in meinem Buch gut. Achten Sie auf Grues.

...

Quelle
Translate

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

Sie sollten sich auch die Pattern-Klasse ansehen.

Quelle
Translate

Eine weitere Abstimmung 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), haben Sie eine ausführbare Spezifikation der Sprache, die sich hervorragend zum Testen eignet, ein Segen für die Dokumentation und eine große Zeitersparnis, wenn Sie sich jemals dazu entschließen, es zu portieren.

Quelle
SaM
Translate

Wenn dies Befehlszeilen analysieren soll, würde ich die Verwendung vorschlagenCommons Cli.

Die Apache Commons CLI-Bibliothek bietet eine API für die Verarbeitung von Befehlszeilenschnittstellen.

Quelle
Translate

VersuchenJavaCCein Parser-Generator für Java.

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

Quelle
Translate

@CodingTheWheel Hier ist dein Code, ein bisschen aufräumen und durch Eclipse (Strg+Verschiebung+f) und die 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;
}
Quelle
Translate

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

Hier ist ein Beispiel mit einem Tokenizer:

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 für die Argumente weiter verwendet werden. Dies alles setzt voraus, dass in den Argumenten keine Leerzeichen verwendet werden. Daher möchten Sie möglicherweise Ihren eigenen einfachen Analysemechanismus verwenden (z. B. das Abrufen des ersten Leerzeichens und die Verwendung von Text zuvor als Aktion oder die Verwendung eines regulären Ausdrucks, wenn Sie nichts dagegen haben Speed Hit), abstrahieren Sie es einfach, damit es überall verwendet werden kann.

Quelle
Translate

Wenn die Trennzeichenfolge für den Befehl immer dieselbe Zeichenfolge oder dasselbe Zeichen (wie das ";") ist, empfehlen wir 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 von der String-Klasse selbst, method split, seit 1.4 verwendet werden können. Es verwendet die Pattern-Klasse aus dem Paket java.util.regex

Muster

Quelle
Translate

Wenn die Sprache so einfach wie einfach ist

VERB NOMEN

dann funktioniert das Teilen von Hand gut.

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

Ich habe ein Tutorial zu ANTLR (v2) beihttp://javadude.com/articles/antlrtutDas gibt Ihnen eine Vorstellung davon, wie es funktioniert.

Quelle
Translate

JCommanderscheint ganz gut zu sein, obwohl ich es noch nicht getestet habe.

Quelle
Translate

Wenn Ihr Text einige Trennzeichen enthält, können Sie IhresplitMethode.
Wenn Text unregelmäßige Zeichenfolgen enthält, bedeutet dies ein anderes Format, das Sie verwenden müssenregular expressions.

Quelle
Translate

Die split-Methode kann eine Zeichenfolge in ein Array des angegebenen Teilzeichenfolgenausdrucks aufteilenregex. Seine Argumente in zwei Formen, nämlich: split (String regex) und split (String regex, int limit), die sich aufteilten (String regex) ist eigentlich durch Aufrufen von split (String regex, int limit) zu erreichen,Limit ist 0. Dann, wenn dieLimit> 0undLimit <0repräsentiert was?

Wenn derjdkerklärt: wannLimit> 0Sub-Array-Längen bis zur Begrenzung, dh wenn möglichLimit-1Unterteilung, die als Teilzeichenfolge verbleibt (außer durch das 1-fache des Zeichens hat das Ende der Zeichenfolge geteilt);

Limit <0gibt keine Begrenzung der Länge des Arrays an;

limit = 0Ende der Zeichenfolge Die leere Zeichenfolge wird abgeschnitten.StringTokenizerDie Klasse ist aus Kompatibilitätsgründen und wird als Legacy-Klasse beibehalten. Daher sollten wir versuchen, die Split-Methode der String-Klasse zu verwenden. beziehen aufVerknüpfung

Quelle