Foros del Web » Programación para mayores de 30 ;) » Java »

Reto de Expresiones Regulares

Estas en el tema de Reto de Expresiones Regulares en el foro de Java en Foros del Web. Hola gente del foro, hoy traigo un problemita que me gustaria me echaran una mano, el tema es sobre Expresiones Regulares y a continuación les ...
  #1 (permalink)  
Antiguo 21/02/2007, 09:57
 
Fecha de Ingreso: octubre-2003
Ubicación: Los Mochis, México.
Mensajes: 81
Antigüedad: 20 años, 6 meses
Puntos: 0
Reto de Expresiones Regulares

Hola gente del foro, hoy traigo un problemita que me gustaria me echaran una mano, el tema es sobre Expresiones Regulares y a continuación les detallo la situación:

Vamos a decir que tengo un archivo HTML que necesito leer y extraer cierta información que se encuentra entre ciertos tags.
Veamos el siguiente ejemplo:

Código:
<tag1>
       a
       b
       c
       <cont>
            bla bla
       </cont>
       <cont>
            ye ye
       </cont>
</tag1>
Yo necesito extraer lo que hay entre el <tag1> y <cont>, es decir, yo esperaría que me regresara "a b c".
Utilizo la siguiente expresión regular:
"<tag1>([\\p{Lower}\\p{Upper}\\p{Digit}\\n\\r\\t\\s\\p{Punc t}]*)<cont>"

Bueno, pues sucede algo muy curioso, me regresa hasta el 2do <cont>, como si ignorara el primero que se encuentra. Ahora bien, hice también la prueba añadiendo un 3er "segmento" de tags <cont>x</cont> y me regresa hasta el 3er tag, en otras palabras siempre me regresa hasta el último.

NOTA: Cabe señalar que no puedo(me regaña el jefe jeje) utilizar métodos como "abc".indexOf("b"), o substring(x,x) o cosas similares, pues tendría que retrabajar demasiado, además de que el performance es mejor si utilizo regex.

Saludos y espero sus respuestas.
Gracias Gente!
__________________
Te amo flakita (jrk)
  #2 (permalink)  
Antiguo 21/02/2007, 14:06
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Re: Reto de Expresiones Regulares

Hola:

¿Dónde utilizas el regex? Esoy mirando por la API y solo veo dos posibles métodos:
Uno para indicar si cumple o no el patrón.
Otro para partir la cadena, pero alrededor del patrón, es decir, te devolvería todo lo demás menos el patrón.

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #3 (permalink)  
Antiguo 21/02/2007, 15:38
 
Fecha de Ingreso: octubre-2003
Ubicación: Los Mochis, México.
Mensajes: 81
Antigüedad: 20 años, 6 meses
Puntos: 0
Re: Reto de Expresiones Regulares

Gracias por contestar chuidiang,
con regex me refiero a Expresiones Regulares, no es que sea algún objeto, método o algo similar, lo escribi así para evitar poner "Expresiones Regulares".
Voy a poner parte del código que tengo, espero sirva de referencia...

Código:
/* pattern to get the top segment */
String patternTopSegment = "(<tag1>([\\p{Lower}\\p{Upper}\\p{Digit}\\n\\r\\t\\s\\p{Punct}]*)<cont>)";
Pattern pattern = Pattern.compile(patternTopSegment);
Matcher matcher2 = pattern.matcher("");		   
matcher2.reset(finalReplacement);		    
boolean matchFound2 = matcher2.find();
la variable finalReplacement es un string que contiene lo siguiente:
Código:
<tag1>
       a
       b
       c
       <cont>
            bla bla
       </cont>
       <cont>
            ye ye
       </cont>
</tag1>
Al ejecutar el método find() este me regresa TRUE, por lo tanto sé que hizo match en el string que puse en el primer post, mas sin embargo no me regresa exactamente lo que quiero.

Ahora, quiero pensar que tengo mal mi patternTopSegment, pero no se que. O quizá sea otra cosa, en realidad no lo se...

Agradezco su tiempo. Espero me puedan ayudar.
Saludos!
__________________
Te amo flakita (jrk)
  #4 (permalink)  
Antiguo 21/02/2007, 16:05
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 19 años, 7 meses
Puntos: 454
Re: Reto de Expresiones Regulares

Hola:

Sigo sin verlo claro. ¿Por qué no podes el código completo, hasta el sitio en el que obtienes la subcadena que quieres, aunque sea equivocada?. Vaya, algo que yo pueda copiar/pegar en el eclipse y ver qué pasa.

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #5 (permalink)  
Antiguo 21/02/2007, 16:33
 
Fecha de Ingreso: octubre-2003
Ubicación: Los Mochis, México.
Mensajes: 81
Antigüedad: 20 años, 6 meses
Puntos: 0
Re: Reto de Expresiones Regulares

Bueno, hice un ejemplito que cualquiera lo puede ejecutar para probar.
Espero con esto quede mas claro...

Código:
/**
 * Example class
 */
package com.pp.lgs.action;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author rortiz
 *
 */
public class RegularExpressionsExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
		/* se declara la variable que va contener todo el string a analizar */
		StringBuffer inputStr = new StringBuffer();
		/* Se le asigna la información */
		inputStr.append("<tag1>\n");
		inputStr.append("a\n");
		inputStr.append("b\n");
		inputStr.append("c\n");
		inputStr.append("<cont>\n");
		inputStr.append("bla bla\n");
		inputStr.append("</cont>\n");
		inputStr.append("<cont>\n");
		inputStr.append("ye ye\n");
		inputStr.append("</cont>\n");
		inputStr.append("</tag1>");	       
		/* se declara el patrón a buscar en el string */
	    String patternRegex = "(<tag1>([\\p{Lower}\\p{Upper}\\p{Digit}\\n\\r\\t\\s\\p{Punct}])<cont>)";
	    /* se compila el patrón */
	    Pattern pattern = Pattern.compile(patternRegex);
	    /* se inicializa el matcher */
	    Matcher matcher = pattern.matcher("");
	    /* se le asigna el string en donde va buscar el patrón definido previamente */
	    matcher.reset(inputStr.toString());
	    /* ejecuta la búsqueda */
	    boolean matchFound = matcher.find();
	    
	    /* se evalúa si encontró algo */
	    if (matchFound){
	    	System.out.println("Grupos encontrados: " + String.valueOf(matcher.groupCount()));
	    	System.out.println(matcher.group(1)); /* se imprime lo que encontró (el grupo 1, aunque puede haber más) */
	    }
	    else {
	    	System.out.println("No se encontró el patrón");
	    }
		}
		catch (Exception e){
			System.out.println("Ha ocurrido un error al procesar la petición");			
		}
	}

}
__________________
Te amo flakita (jrk)
  #6 (permalink)  
Antiguo 21/02/2007, 19:21
 
Fecha de Ingreso: octubre-2003
Ubicación: Los Mochis, México.
Mensajes: 81
Antigüedad: 20 años, 6 meses
Puntos: 0
Re: Reto de Expresiones Regulares

Perdón, error en el pattern. Queda como sigue:
Código:
String patternRegex = "<tag1>([\\p{Lower}\\p{Upper}\\p{Digit}\\n\\r\\t\\s\\p{Punct}]*)<cont>";
__________________
Te amo flakita (jrk)
  #7 (permalink)  
Antiguo 21/02/2007, 20:01
Avatar de xknown  
Fecha de Ingreso: diciembre-2004
Ubicación: Cusco - Perú
Mensajes: 2.248
Antigüedad: 19 años, 4 meses
Puntos: 7
Re: Reto de Expresiones Regulares

No uso java, pero me parece que la expresión regular es sencilla: <tag1>(.*?)<cont>

Para que esa expresión funcione, necesitas especificar que "." también incluya los caracteres \r, \n; este es el código que generó la herramienta que uso:
Código:
try {
    Pattern Regex = Pattern.compile("<tag1>(.*?)<cont>",
        Pattern.CANON_EQ | Pattern.DOTALL);
    Matcher RegexMatcher = Regex.matcher(SubjectString);
    if (RegexMatcher.find()) {
        // RegexMatcher.group(); RegexMatcher.start(); RegexMatcher.end();
    } else {
        
    } 
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}
Ignoro si finalmente te llegue a funcionar o no esta última porción de código.

Saludos
__________________
Alex Concha
Buayacorp - Programación y Diseño
  #8 (permalink)  
Antiguo 22/02/2007, 09:15
 
Fecha de Ingreso: octubre-2003
Ubicación: Los Mochis, México.
Mensajes: 81
Antigüedad: 20 años, 6 meses
Puntos: 0
Re: Reto de Expresiones Regulares

Gracias xknown, sólo que con esa expresión regular lo estaría "casando" de alguna forma con el orden de los caracteres, es por eso que se tiene que meter dentro de un conjunto con los [], de hecho hice esa misma prueba...algo así como ([.*?\\n\\r]*) pero no me funcionó, el punto "." no me funciona dentro del conjunto, la verdad no se porqué, es por eso que lo hice con \\p{Lower}\\p{Upper}..etc
Pero bueno, agradezco tu tiempo y si lo puedo resolver lo posteo para que TODO EL MUNDO SE ENTERE jeje

Saludos desde Monterrey, México
Have a nice day!
Ray*
__________________
Te amo flakita (jrk)
  #9 (permalink)  
Antiguo 22/02/2007, 16:18
 
Fecha de Ingreso: octubre-2003
Mensajes: 3.578
Antigüedad: 20 años, 6 meses
Puntos: 51
Re: Reto de Expresiones Regulares

Ummm, ahora no tengo tiempo de probarlo, pero hay una "opcion" en expresiones regulares que dice si una expresion, en caso de tener mas de un posible aciertos (match) si ha de escoger la primera que encuentre (texto más corto) o la más grande.

Por lo que dices parece ser que tu querrias que cogiese la primera y te esta cogiendo la mayor, así que busca en las expresiones regulares como cambiarle esa opción y podrás indicarle que coja la primera expresión que cumpla el criterio.

No recuerdo ahora como se hacia pero el problema es que te está devolviendo un resultado correcto, ya que lo que te da tambien cumple las expresiones regulares, pero no el que tu quieres.

Recuerdo que hice una implementacion de BBCode para un foro y me paso algo parecido, la reviso mañana y te digo como lo solucione en mi caso, aunque no se si te servirá.
  #10 (permalink)  
Antiguo 22/02/2007, 16:20
 
Fecha de Ingreso: octubre-2003
Ubicación: Los Mochis, México.
Mensajes: 81
Antigüedad: 20 años, 6 meses
Puntos: 0
Re: Reto de Expresiones Regulares

Resuelto señores, les dejo la expresión con la que tuve éxito.

Código:
<tag1>([\u0000-\uffff]*<cont>)
Por si alguna vez se llegan a topar con lo mismo.

Saludos!
__________________
Te amo flakita (jrk)
  #11 (permalink)  
Antiguo 22/02/2007, 19:46
 
Fecha de Ingreso: octubre-2003
Ubicación: Los Mochis, México.
Mensajes: 81
Antigüedad: 20 años, 6 meses
Puntos: 0
Re: Reto de Expresiones Regulares

Gracias GreenEyed, casualmente casi en el momento en que posteaste yo postee la respuesta.
Checa la hora de mi post y el tuyo, creo que estabamos escribiendo al mismo tiempo jeje.
Gracias de cualquier forma, en mi post anterior puse la solución.

Saludos cordiales!!

Ray*
__________________
Te amo flakita (jrk)
  #12 (permalink)  
Antiguo 14/04/2008, 14:59
 
Fecha de Ingreso: abril-2008
Mensajes: 1
Antigüedad: 16 años
Puntos: 0
Exclamación Re: Reto de Expresiones Regulares

saludos luiguiray,
se que este foro se abrio el año pasado,
yo hasta ahora estoy empezando con lo de las
expresiones regulares en java, segun tu reto que
colocaste se dieron muchas soluciones buenas,
estas tres sintaxis de patrones:

String patternRegex = "<tag1>(.*)<cont>";

String patternRegex = "<tag1>([\\p{Lower}\\p{Upper}\\p{Digit}\\n\\r\\t\\s\\p{Punc t}]*)<cont>";

String patternRegex = "<tag1>([\u0000-\uffff]*<cont>)

Sin duda estas son buenas soluciones, pero sigues con el problema inicial
el resultado para las tres es el mismo:

<tag1>
a
b
c
<cont>
bla bla
</cont>
<cont>

la idea era que el resultado fuera este:

<tag1>
a
b
c
<cont>


He estado intentando y aun no lo he conseguido,
si ustedes hallaron la solucion definitiva les agradeceria
compartieran, y cualquier documentacion que tengan o tutoriales
les agradeceria

saludos...
  #13 (permalink)  
Antiguo 14/04/2008, 15:39
 
Fecha de Ingreso: octubre-2003
Ubicación: Los Mochis, México.
Mensajes: 81
Antigüedad: 20 años, 6 meses
Puntos: 0
Mensaje Re: Reto de Expresiones Regulares

Hola elipse,

La verdad no me quedo claro lo que quieres hacer, puedes incluir por favor tu codigo?,

Saludos
__________________
Te amo flakita (jrk)
  #14 (permalink)  
Antiguo 15/04/2008, 12:22
 
Fecha de Ingreso: abril-2008
Mensajes: 1
Antigüedad: 16 años
Puntos: 0
Re: Reto de Expresiones Regulares

Guenas.

Hola elipse. El problema que tienes esta en el metacaracter *

Este metacaracter siempre trata de expandirse hasta ocupar el maximo posible, por eso esta llegando hasta el segundo "cont".
Si deseas que se expanda el minimo debes usar ? detras del *.

Prueba esto:

String patternRegex = "<tag1>([\\p{Lower}\\p{Upper}\\p{Digit}\\n\\r\\t\\s\\p{Punc t}]*?)<cont>";

Como veras es igual que el que se mostraba pero añadiendo el interrogante detras del asterisco.

Un saludo,
Papez
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 01:53.