PDA

Ver la Versión Completa : [ CONSULTA ] Como leer y tratar texto multilinea


diamant-x
19/05/10, 00:15:03
Hola,
Hasta ahora me había apañado navegando y buscando mucho por internet pero no soy capaz de encontrar respuesta a esta pregunta.

Tengo un archivo de texto con múltiples lineas. Este texto no presenta ninguna forma recurrente con el que poder parsear al estilo JSON, o XML. Con que tipo de variables puedo tratar dicho texto para poder hacer cosas?
Si intento guarda el contenido en un String sólo obeingo la primera linea, lo mismo con CharSequence,... no he probado StringBuilder pues no se como usarlo.

Alguien puede echarme una mano? Gracias.

diamant-x
30/05/10, 14:43:52
He indagado y por lo visto el sistema es leer todo el contenido en un BufferedReader, e ir importando cada linea al String en cuestión a base de reader.ReadLine().

Ahora sólo me queda saber como parsear texto en busca de palabras concretas y que me devuelva su posición ^^'. Alguien por aquí tiene alguna mínima noción de si existe alguna comanda en concreto o voy a tener que currarme toda una función desde cero para dicho cometido? ^^'

Capitan Trueno
30/05/10, 15:30:37
He indagado y por lo visto el sistema es leer todo el contenido en un BufferedReader, e ir importando cada linea al String en cuestión a base de reader.ReadLine().

Ahora sólo me queda saber como parsear texto en busca de palabras concretas y que me devuelva su posición ^^'. Alguien por aquí tiene alguna mínima noción de si existe alguna comanda en concreto o voy a tener que currarme toda una función desde cero para dicho cometido? ^^'

Hola,
si no me equivoco, puedes probar con la función 'indexOf'. Cualquier String puede hacer uso de ella:

String miString = reader.readString();
int indice = miString.indexOf("cadena");
if ( índice != null ) {
String valor = miString.substring(indice, 6);
} else {
// miString no contiene el texto 'cadena'
}

Un saludo!

diamant-x
30/05/10, 16:42:24
Wo, gracias por la referencia.
Pero y si ese texto "cadena" aparece más de una vez en la String, supongo que no te lo indica y simplemente tendras qu eir ejecutando un indexOf("cadena", posicion_primera_cadena) hasta que devuelva -1, no?

Miraré a ver que tal, gracias! ^^

Capitan Trueno
30/05/10, 17:33:07
Wo, gracias por la referencia.
Pero y si ese texto "cadena" aparece más de una vez en la String, supongo que no te lo indica y simplemente tendras qu eir ejecutando un indexOf("cadena", posicion_primera_cadena) hasta que devuelva -1, no?

Miraré a ver que tal, gracias! ^^

Hola,

me parece que no, sólo te devuelve la primera ocurrencia. Mételo dentro de un bucle y haz un debug para probarlo.

Un saludo!

diamant-x
12/06/10, 03:32:15
Hola,

me parece que no, sólo te devuelve la primera ocurrencia. Mételo dentro de un bucle y haz un debug para probarlo.

Un saludo!

Hola, Bueno he sacado algo de tiempo (las mejores horas para programar siempre son por la noche xD) y he comprobado que a diferencia de lo que pensabamos, IndexOf devuelve la ULTIMA ocurrencia empezando dsd el principio del string.
Existe otra comanda ke es LastIndexof que devuelve la primera ocurrencia pero empieza a buscar de atrás para adelante.. :S

Ya me romperé el coco mañana para ver como me lo monto para que vaya uno a uno ke es lo que quiero ^^'

Capitan Trueno
12/06/10, 13:39:10
Hola, Bueno he sacado algo de tiempo (las mejores horas para programar siempre son por la noche xD) y he comprobado que a diferencia de lo que pensabamos, IndexOf devuelve la ULTIMA ocurrencia empezando dsd el principio del string.
Existe otra comanda ke es LastIndexof que devuelve la primera ocurrencia pero empieza a buscar de atrás para adelante.. :S

Ya me romperé el coco mañana para ver como me lo monto para que vaya uno a uno ke es lo que quiero ^^'

Hola,

¿estás seguro de eso? A mi me suena que para en la primera ocurrencia... No he tenido tiempo de montar un ejemplo de prueba, pero he encontrado a alguien que sí lo ha hecho, pégale un vistazo y ya cuentas cómo has quedado ;-)

Un saludo!
http://lineadecodigo.com/java/contador-de-ocurrencias-en-java/

diamant-x
12/06/10, 14:41:44
He releido todas la funciones y veo que exactamente la función presenta algunos "problemas" segun que argumentos se introduzcan.

StringA.indexOf(StringB) devuelve la primera posicion de StringB empezando dsd el principio de StringA, pero la gracia es ir detectando las siguientes ocurrencias a partir de un punto, por lo que empleo StringA.indexOf(StringB, int_posicion_inicio) pero es cuando uso esta funcion que me devuelve la ultima ocurrencia :S

http://developer.android.com/reference/java/lang/String.html#indexOf%28java.lang.String,%20int%29

Analizando el codigo de la web que has adjuntado veo que va particionando la String a medida ke vaya encontrando la palabra clave, pero eso no puede generar un consumo de CPU muy elevado ?

Edito: Efectivamente, así lo he hecho con el procedimiento ke usan en ese fragmento de ir "recortando" el string original y funciona bien. aunque tarda un poquito para mi gusto, pero supongo ke es porque la cadena original presenta muchas ocurrencias. Pero bueno, funciona, que es lo que quiero xD.
Gracias! Si sabes de algun otro método que no involucre el "recortar" la cadena y pueda acelerar el proceso se agradeceria :P.

Capitan Trueno
12/06/10, 21:07:12
Me alegra que Lo hayas resuelto :D

ocapocap
17/06/10, 10:21:48
Como bien indicáis, el método indexOf tiene un segundo parámetro que es la posición de inicio en la que queremos buscar, así que lo único que hay que hacer es modificar ese valor con la posición de la ocurrencia anterior.

Si no se encuentra, retorna un valor -1.

Así que podríamos emplear el siguiente código:

int pos = cadena.indexOf(buscar);
while (pos != -1) {
... // Hacer lo que sea con la posición pos
// Seguimos buscando...
pos = cadena.indexOf(buscar, pos + buscar.length());
}

Si en la búsqueda no quieres tener en cuenta mayúsculas y minúsculas, emplea

cadena.toUpperCase().indexOf(buscar.toUpperCase())

Un saludo

diamant-x
18/06/10, 16:00:47
Como bien indicáis, el método indexOf tiene un segundo parámetro que es la posición de inicio en la que queremos buscar, así que lo único que hay que hacer es modificar ese valor con la posición de la ocurrencia anterior.

Si no se encuentra, retorna un valor -1.

Así que podríamos emplear el siguiente código:

int pos = cadena.indexOf(buscar);
while (pos != -1) {
... // Hacer lo que sea con la posición pos
// Seguimos buscando...
pos = cadena.indexOf(buscar, pos + buscar.length());
}

Si en la búsqueda no quieres tener en cuenta mayúsculas y minúsculas, emplea

cadena.toUpperCase().indexOf(buscar.toUpperCase())

Un saludo

Pero haciendo eso pasa lo que comentaba antes:

StringA.indexOf(StringB) devuelve la primera posicion de StringB empezando dsd el principio de StringA, [...]

empleo StringA.indexOf(StringB, int_posicion_inicio) pero es cuando uso esta funcion que me devuelve la ultima ocurrencia

po rlo que, sin compilar, diria que tu codigo me fallarà en cuanto intente encontrar mas de 2 veces "buscar", Ya que la primera vez me lo encontrarà la primera ya que usas indexOf(buscar), pero las siguientes estas usando indexOf(buscar, int) donde al añadirle ese segundo argumento la funcion indexOf deja de devolver la primera ocurrencia y nos devuelve la última, por lo que en tu codigo al buscar "buscar" por segunda vez nos devolverá directamente la ultima ocurrencia de buscar, omitiendo cualquier otra vez que pudiese aparecer y acabando la funcion siempre con dos "buscar" encontrados.

----------------
Estoy escuchando: Haddaway – What Is Love (http://www.foxytunes.com/artist/haddaway/track/what+is+love?locale=es-ES) en mi Spotify via FoxyTunes (http://www.foxytunes.com/signatunes/)

ocapocap
18/06/10, 22:08:28
El código funciona correctamente. La función indexOf(campo, pos) busca la primera aparición del campo a partir de la posición pos, por lo que si la cadena "campo" aparece varias veces, el código de ejemplo te encontrará todas ellas.

Pruébalo que ya verás como funciona.

Un saludo

Capitan Trueno
18/06/10, 22:22:53
Pero haciendo eso pasa lo que comentaba antes:



po rlo que, sin compilar, diria que tu codigo me fallarà en cuanto intente encontrar mas de 2 veces "buscar", Ya que la primera vez me lo encontrarà la primera ya que usas indexOf(buscar), pero las siguientes estas usando indexOf(buscar, int) donde al añadirle ese segundo argumento la funcion indexOf deja de devolver la primera ocurrencia y nos devuelve la última, por lo que en tu codigo al buscar "buscar" por segunda vez nos devolverá directamente la ultima ocurrencia de buscar, omitiendo cualquier otra vez que pudiese aparecer y acabando la funcion siempre con dos "buscar" encontrados.

----------------
Estoy escuchando: Haddaway – What Is Love (http://www.foxytunes.com/artist/haddaway/track/what+is+love?locale=es-ES) en mi Spotify via FoxyTunes (http://www.foxytunes.com/signatunes/)


Hola,

he modificado el código del ejemplo que te enlacé para que veas cómo se comporta. El código es esté:
public class ContadorDePalabras {

public static void main(String[] args) {

// Texto
String sTexto = "palabra o palabra y palabra";
// Texto que vamos a buscar
String sTextoBuscado = "palabra";
// Contador de ocurrencias
int contador = 0;
// Contador de caracteres recorridos sTextoBuscado
int posicionActual = 0;
int posicionFinal = 0;

System.out.println("Cadena Origen: "+ sTexto);
System.out.println("\nCadena a buscar: "+ sTextoBuscado);

while (sTexto.indexOf(sTextoBuscado) > -1) {
posicionActual += sTexto.indexOf(sTextoBuscado);
posicionFinal = posicionActual + sTextoBuscado.length();
contador++;
System.out.println("\nOcurrencia n."+contador);
System.out.println("\n\t=>Del caracter "+ posicionActual +" al caracter "+ posicionFinal);
sTexto = sTexto.substring(sTexto.indexOf(
sTextoBuscado)+sTextoBuscado.length(),sTexto.lengt h());

posicionActual = posicionFinal;
}

System.out.println (contador);
}
}Y los resultados que ofrece son éstos:
C:\Users\CT>java ContadorDePalabras
Cadena Origen: palabra o palabra y palabra

Cadena a buscar: palabra

Ocurrencia n.1

=>Del caracter 0 al caracter 7

Ocurrencia n.2

=>Del caracter 10 al caracter 17

Ocurrencia n.3

=>Del caracter 20 al caracter 27

Ocurrencias TOTALES: 3
Adjunto el fichero java para que lo modifiques y hagas las pruebas que necesites. Para compilarlo y ejecutarlo, pues los pasos de siempre y donde siempre. Puedes compilarlo desde un terminal de Linux o de una consola de MS-DOS de Windows, con un simple javac ContadorDePalabras.java.

Para ejecutarlo simplemente escribe java ContadorDePalabrasEspero que estos resultados, te sirvan para tu propósito.

Un saludo! ;-)

diamant-x
18/06/10, 22:46:07
Si si, si con el procedimiento de recortar la string me va de perlas como ya comenté, pero si aplicamos el método de ocapocap sólo me devolvia la ultima entrada a partir de la posicion pos.

Tal y como se ve en el enlace al androdi developers:
public int indexOf (String (http://developer.android.com/reference/java/lang/String.html) subString, int start)

Searches in this string for the index of the specified string.

Mientras que con un solo argumento:
public int indexOf (String (http://developer.android.com/reference/java/lang/String.html) string)

Searches in this string for the first index of the specified string.

ocapocap
19/06/10, 11:19:32
Hola de nuevo,

El indexOf funciona tal y como te he dicho. El código que he utilizado:

buscar = (EditText) this.findViewById(R.id.EditText01);
texto = (TextView) findViewById(R.id.TextView01);
texto.setText("Esto es un texto de prueba.\nEsto es un texto de prueba.\nEsto es un texto de prueba.\nEsto es un texto de prueba");
resultado = (TextView) findViewById(R.id.TextView02);
findViewById(R.id.Button01).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String cadena = texto.getText().toString();
String bus = buscar.getText().toString().toUpperCase();
int pos = cadena.toUpperCase().indexOf(bus);
String resp = "";
while (pos!=-1){
resp +="Encontrada en pos = " + pos + "\n";
pos = cadena.toUpperCase().indexOf(bus,pos+bus.length()) ;
}
resultado.setText(resp);
}
});

Te adjunto el ejemplo. Espero que te sirva.

Un saludo

SergioAndroid
13/07/10, 14:42:53
Si pretendes encontrar patrones... siempre puedes usar expresiones regulares (son un poco puñeteras al principio, pero como te pase como a mi... ahora no sabria vivir sin ellas xD)