¿Cuáles son los diferentes métodos para analizar cadenas en Java? [cerrado]


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

Author: agweber, 2008-08-06

15 answers

Asumo que estás tratando de hacer que la interfaz de comandos sea lo más indulgente posible. Si este es el caso, le sugiero que utilice un algoritmo similar a este:

  1. Leer en la cadena
    • Divide la cadena en tokens
    • Use un diccionario para convertir sinónimos a una forma común
    • Por ejemplo, convierte "hit", "punch", "strike" y "kick"en" hit "
    • Realizar acciones en una base desordenada e inclusiva
    • Desordenado - " puñetazo al mono en el face "es lo mismo que"the face in the monkey punch"
    • Inclusive - Si se supone que el comando es "punch the monkey in the face" y suministran "punch monkey", debe verificar cuántos comandos coinciden. Si solo hay un comando, haga esta acción. Incluso podría ser una buena idea tener prioridades de comando, e incluso si hubiera incluso coincidencias, realizaría la acción superior.
 14
Author: andrewrk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-06 00:42:00

Me gustan mucho las expresiones regulares. Siempre y cuando las cadenas de comandos sean bastante simples, puede escribir algunas expresiones regulares que podrían tomar algunas páginas de código para analizar manualmente.

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

 19
Author: Daniel Broekman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-03 05:18:33

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

En la práctica, si los comandos no son muy sofisticados, puede 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 apache commons CLI o args4j (usa anotaciones). Están bien documentados y son muy simples de usar. Manejan el análisis automático y el único lo que necesita hacer es leer campos particulares en un objeto.

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

 13
Author: Bartosz Bierkowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-06 05:29:03

Me gustaría mirar Migraciones Java de Zork, y me inclino hacia un simple Procesador de Lenguaje Natural (impulsado ya sea por tokenización o regex) como el siguiente (de 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 de nuevo es buena en mi libro, solo ten cuidado con las Grues.

...

 7
Author: Justin Standard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-06 16:20:17

El propio Sun recomienda mantenerse alejado de StringTokenizer y usar la cadena.método derramado en su lugar.

También querrá mirar la clase Pattern.

 6
Author: bpapa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-06 16:14:45

Otro voto para ANTLR/ANTLRWorks. Si crea dos versiones del archivo, una con el código Java para ejecutar realmente los comandos, y otra sin (solo con la gramática), entonces tiene una especificación ejecutable del lenguaje, que es excelente para probar, una bendición para la documentación y un gran ahorro de tiempo si alguna vez decide portarlo.

 6
Author: John with waffle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-31 01:38:29

Si esto es para analizar las líneas de comando, sugeriría usar Commons Cli.

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

 4
Author: SaM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-31 01:32:43

Pruebe JavaCC un generador de analizador sintáctico para Java.

Tiene muchas funciones para interpretar idiomas, y está bien soportado en Eclipse.

 4
Author: Alotor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-21 17:44:55

@CodingTheWheel Heres su código, un poco de limpieza y a través de eclipse (ctrl+shift+f ) y el insertado de nuevo aquí:)

Incluyendo los cuatro espacios en frente 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;
}
 2
Author: svrist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-20 22:13:23

Un tokenizador de cadena simple en espacios debería funcionar, pero 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);
}

Entonces se pueden usar tokens para los argumentos. Todo esto asume que no se usan espacios en los argumentos... por lo tanto, es posible que desee desplegar su propio mecanismo de análisis simple (como obtener el primer espacio en blanco y usar el texto anterior como acción, o usar una expresión regular si no le importa el golpe de velocidad), simplemente abstraerlo por lo que se puede utilizar en cualquier lugar.

 1
Author: Mike Stone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-05 23:57:02

Cuando la cadena separadora para el comando es siempre la misma cadena o char (como el ";") y recomienda usar la clase StrinkTokenizer:

StringTokenizer

Pero cuando el separador varía o es complejo y recomendamos usar las expresiones regulares, que pueden ser utilizadas por la propia clase String, method split, desde 1.4. Utiliza la clase Pattern de java.útil.paquete regex

Patrón

 1
Author: Telcontar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-06 15:40:46

Si el lenguaje es simple como

VERBO SUSTANTIVO

Entonces 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 que le dará una idea de cómo funciona.

 1
Author: Scott Stanchfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-16 15:35:53

JCommander parece bastante bueno, aunque todavía tengo que probarlo.

 1
Author: Pierre Gardin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-20 13:59:05

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

 1
Author: Pratik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-24 09:17:03

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

Cuando el jdk explicado: cuando limit> 0 sub-array longitudes hasta el límite, es decir, si es posible, puede ser limit-1 sub-division, permaneciendo como una subcadena (excepto por limit-1 veces que el carácter tiene un final dividido de cadena);

limit indica que no hay límite en la longitud del array;

limit = 0 fin de la cadena la cadena vacía será truncada. StringTokenizer la clase es por razones de compatibilidad y es una clase heredada preservada, por lo que deberíamos intentar usar el método split de la clase String. consulte enlace

 1
Author: shouyu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-27 10:00:40