Pregunta

Para analizar los comandos del reproductor, con mayor frecuencia he usado el dividir método para dividir una cadena por delimitadores y luego simplemente descubrir el resto por una serie de ifs o switches.¿Cuáles son algunas formas diferentes de analizar cadenas en Java?

¿Fue útil?

Solución

Supongo que estás intentando que la interfaz de comando sea lo más indulgente posible.Si este es el caso, te sugiero que utilices un algoritmo similar a este:

  1. Leer en la cadena
    • Dividir la cadena en tokens
    • Utilice un diccionario para convertir sinónimos a una forma común
    • Por ejemplo, convierta "golpear", "puñetazo", "golpear" y "patear", todo en "golpear".
    • Realizar acciones sobre una base inclusiva y desordenada.
    • desordenado - "golpear al mono en la cara" es lo mismo que "golpear la cara del mono"
    • Inclusivo - Si se supone que el comando es "golpear al mono en la cara" y ellos proporcionan "golpear al mono", debes verificar con cuántos comandos coincide.Si solo hay un comando, realice esta acción.Incluso podría ser una buena idea tener prioridades de comando, e incluso si hubiera coincidencias, realizaría la acción principal.

Otros consejos

Me gustan mucho las expresiones regulares.Siempre que las cadenas de comando sean bastante simples, puede escribir algunas expresiones regulares que podrían requerir algunas páginas de código para analizarlas manualmente.

Te sugiero que revises http://www.regular-expressions.info para obtener una buena introducción a las expresiones regulares, así como ejemplos específicos para Java.

Analizar manualmente es muy divertido...al principio:)

En la práctica, si los comandos no son muy sofisticados, puedes tratarlos de la misma manera que los utilizados en los intérpretes de línea de comandos.Hay una lista de bibliotecas que puedes usar: http://java-source.net/open-source/command-line.Creo que puedes empezar con CLI de apache común o args4j (usa anotaciones).Están bien documentados y son realmente sencillos de usar.Manejan el análisis automáticamente y lo único que debe hacer es leer campos particulares en un objeto.

Si tiene comandos más sofisticados, tal vez sería una mejor idea crear una gramática formal.Hay una muy buena biblioteca con editor gráfico, depurador e intérprete de gramáticas.Se llama antlr (y el editor ANTLRTrabaja) y es gratis :) También hay algunos ejemplos de gramáticas y tutoriales.

yo miraría Migraciones Java de Zork, e inclinarse hacia un simple Procesador de lenguaje natural (impulsado por tokenización o expresiones regulares) como el siguiente (desde este enlace):

    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;
    }

...

Cualquier cosa que le dé a un programador una razón para mirar a Zork nuevamente es buena en mi opinión, solo tenga cuidado con Grues.

...

El propio Sun recomienda mantenerse alejado de StringTokenizer y utilizar el método String.spilt en su lugar.

También querrás mirar la clase Pattern.

Otro voto para ANTLR/ANTLRWorks.Si crea dos versiones del archivo, una con el código Java para ejecutar los comandos y otra sin (solo con la gramática), entonces tendrá una especificación ejecutable del lenguaje, lo cual es excelente para realizar pruebas y una gran ayuda para la documentación. , y un gran ahorro de tiempo si alguna vez decides portarlo.

Si esto es para analizar líneas de comando, sugeriría usar CLI común.

La biblioteca CLI de Apache Commons proporciona una API para procesar interfaces de línea de comandos.

Intentar JavaCC un generador de analizadores para Java.

Tiene muchas funciones para interpretar idiomas y es compatible con Eclipse.

@CodingTheWheel Aquí está su código, un poco limpio y a través del eclipse (control+cambio+F) y el insertado de nuevo aquí :)

Incluyendo los cuatro espacios delante de cada línea.

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;
}

Un simple tokenizador de cadenas en espacios debería funcionar, pero en realidad hay muchas maneras de hacerlo.

Aquí hay un ejemplo usando un tokenizador:

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

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

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

Luego, los tokens se pueden utilizar más para los argumentos.Todo esto supone que no se utilizan espacios en los argumentos...por lo que es posible que desee implementar su propio mecanismo de análisis simple (como obtener el primer espacio en blanco y usar texto antes como acción, o usar una expresión regular si no le importa la velocidad), simplemente resúmalo para que pueda usarse en cualquier lugar.

Cuando la cadena separadora del comando es siempre la misma cadena o carácter (como ";"), le recomiendo que utilice la clase StrinkTokenizer:

Tokenizador de cadena

pero cuando el separador varía o es complejo te recomiendo usar las expresiones regulares, que pueden ser utilizadas por la propia clase String, método split, desde 1.4.Utiliza la clase Pattern del paquete java.util.regex

Patrón

Si el lenguaje es muy simple como simplemente

SUSTANTIVO VERBO

luego dividir a mano funciona bien.

Si es más complejo, deberías buscar una herramienta como ANTLR o JavaCC.

Tengo un tutorial sobre ANTLR (v2) en http://javadude.com/articles/antlrtut lo que te dará una idea de cómo funciona.

JComandante Parece bastante bueno, aunque todavía tengo que probarlo.

Si su texto contiene algunos delimitadores, entonces puede split método.
Si el texto contiene cadenas irregulares significa que tiene un formato diferente, entonces debe usar regular expressions.

El método de división puede dividir una cadena en una matriz de la expresión de subcadena especificada. regex.Sus argumentos en dos formas, a saber:dividir (String regex) y dividir (String regex, int limit), que se dividió (String regex) en realidad es llamando a split (String regex, int limit) para lograrlo, el límite es 0.Entonces, cuando el límite> 0 y límite <0 ¿representa qué?

Cuando el jdk explicado:cuando límite> 0 longitudes de subconjunto hasta el límite, es decir, si es posible, se pueden límite-1 subdivisión, permaneciendo como una subcadena (excepto por el límite de 1 vez que el carácter tiene el extremo dividido de la cadena);

límite <0 indica que no hay límite en la longitud de la matriz;

límite = 0 El final de la cadena se truncará.StringTokenizer La clase es por razones de compatibilidad y se conserva como clase heredada, por lo que deberíamos intentar utilizar el método de división de la clase String.Referirse a enlace

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top