Mostrando entradas con la etiqueta Expresiones Regulares. Mostrar todas las entradas
Mostrando entradas con la etiqueta Expresiones Regulares. Mostrar todas las entradas

lunes, 13 de julio de 2009

Expresiones Regulares. II Parte

    Ahora que ya conocemos los metacaracteres, sus significados y reglas, veamos ahora como podemos utilizarlo para hacer que nuestras cadenas de caracteres puedan coincidir con los patrones:

La Clase Pattern: (Patrón):


    En las expresiones regulares de java la clase Pattern tiene varios métodos que nos sirven para establecer el patrón y buscar coincidencias, veamos:Métodostatic Pattern compile(String regex)
    Permite compilar una expresión regular para uso posterior como un patrón. Si la expresión regular tiene un error el compilador no permite la compilación.
El error mas común es: “Invalid escape sequence”.
Ejemplo:


Pattern patron = Pattern.compile("\w*");


Este código lanza un error ya que se deben colocar una barra invertida adicional para que la expresión \w tome efecto de la siguiente manera:

Pattern patron = Pattern.compile("\\w*");

Ahora si nuestro patrón está compilado y listo para usarse en cualquier parte del código, en este caso coincidirá con cualquier palabra que use sólo letras y/o números.

Método
static boolean matches(String regex, CharSequence input)
Sirve para hacer coincidir una expresión regular con una entrada, es muy útil si sabemos que la expresión regular se utilizará una sola vez.
Ejemplo:

System.out.println(Pattern.matches("\\w*","cadena2")); //Consola muestra true


Método
Matcher matcher(CharSequence entrada)
Devuelve un matcher que permitirá posteriormente buscar coincidencias con el patrón.Ejemplo:

Pattern patron = Pattern.compile("\\s*palabra");
Matcher m = patron.matcher("\t\t palabra");
if(m.matches()){
    System.out.println("Patron coincide");
}else{
    System.out.println("Patron No coincide");
}//Imprime Patron coincide


Método
String pattern()
Devuelve la expresión regular (como una cadena de caracteres) compilada por el método compile.Ejemplo:

Pattern patron = Pattern.compile("\\s*palabra");
System.out.println(patron.pattern());
//Se imprime \s*palabra


Método
String[] split(CharSequence entrada)
String[] split(CharSequence entrada, int limite)

Devuelve un arreglo de cadenas que resulta al separar la cadena entrada con la expresion regular, omitiendo la expresion regular.Ejemplo:

Pattern patron = Pattern.compile("\\s*palabra");
String[] cadenas = patron.split("uno palabra dos");
for(String fragmento: cadenas){
    System.out.print(fragmento.trim()+" ");
}
//Imprime uno dos

  La variante con límite, tiene tres modalidades, si límite es un entero positivo se aplicará al menos el límite menos 1 veces; si es cero, se aplicara tantas veces como se pueda eliminándose las cadenas vacías y por último
si es negativo es igual a cero pero se dejan las cadenas vacías.




    A continuación un código que utiliza las expresiones regulares para mostrar todas las clases que se encuentran dentro de un archivo java siempre y cuando la clase no extienda de ninguna clase y no implemente interfaces. La clase se llama Buscadora y cuando se va a utilizar hay que pasar como parámetro el archivo de clase al que se le quiere encontrar todas sus clases. Por ejemplo:

java Buscadora ClaseDestino.java

Aqui el codigo:


import java.io.*;
import java.util.regex.*;
import javax.swing.JOptionPane;

public class Buscadora {
  public static void main(String[] args) {
    BufferedReader entrada = null;
    String texto = "";
    String[] cadenas = null;
    Matcher m = null;
    Pattern patronBusqueda = Pattern.compile("\\s*\\w*\\s*\\w*\\s*class\\s*\\w*\\s*\\W*");
    Pattern patronSplit = Pattern.compile("\\s*\\w*\\s*\\w*\\s*class");

    try {
      File archivo = new File(args[0]);
      FileReader fr = new FileReader(archivo);
      entrada = new BufferedReader(fr);
      System.out.println(args[0]);
      while((texto = entrada.readLine()) != null){
        m = patronBusqueda.matcher(texto);
        if(m.matches()){
          cadenas = patronSplit.split(texto,0);
          for(String cadena: cadenas){
            cadena = cadena.replace("{", " ");
            cadena = cadena.replace("}", " ");
            if(cadena.trim().length() == 0)
              continue;
            System.out.println("Nombre de la clase: "+cadena.trim());
          }
        }
      }
    } catch (ArrayIndexOutOfBoundsException e) {
      JOptionPane.showMessageDialog(null, "Debe especificar un archivo como paramentro");
    } catch (FileNotFoundException e) {
      JOptionPane.showMessageDialog(null, "Error. Archivo no encontrado");
    } catch (IOException e){
      JOptionPane.showMessageDialog(null, "Error al leer archivo");
    }
  }
}


    Como puede ver se utilizan dos patrones, uno para verificar que la línea que se compara coincida con una linea de declaración de una clase y el otro patrón para romper la cadena (split) y obtener así el nombre de la clase.

También es importante mencionar que el primer patrón (patronBusqueda) utiliza el metacaracter \W para hacerla coincidir con un caracter de no palabra, en este caso puede ser una llave "{" o "}". Otros utilizados son los caracteres de palabra \w y de espacio en blanco o tabulador \s.

martes, 30 de junio de 2009

Nuevos temas desde ahora

Saludos lectores, me he dado a la tarea de seguir buscando información acerca de las innovaciones de java 5.0, que son los temas que estamos desarrollando, a nivel de codificación no he visto otras innovaciones, se podría haber profundizado más por la extensión y tela que cortar que tiene java pero, por ahora, lo dejaremos hasta allí. Las innovaciones que he encontrado son a nivel de optimización de uso de recursos de hardware y reducción del tiempo de programación.

Ahora tomaremos otros temas que aunque son del jdk 1.4 no están obsoletos porque siguen vigentes en la versión 5. Los temas que se desarrollanrán son:

Expresiones Regulares (paquete java.util.regex),

Aserciones (Clase AssertionError del paquete java.lang)

Sistema de Registros de java (paquete lava.util.logging)

Comencemos:

Expresiones Regulares: I parte

Las expresiones regulares en Java son cadenas de texto que sirven de patrón para realizar búsquedas de otras cadenas buscando hacerlas coincidir con dicho patrón, los patrones generalmente contienen metacaracteres que permiten generalizar su significado, por ejemplo: Si queremos encontrar la palabra cuerpo podemos escribirla completamente y su significado será literal, pero si queremos buscar todas las cadenas que comiencen por c. ¿Cómo se hará? Si, la respuesta es con expresiones regulares.

Las expresiones regulares han tenido una evolución y permiten ahora un gran número de posibilidades para encontrar patrones dentro de cadenas. Las expresiones regulares en Java funcionan a través de tres elementos:

Metacaracteres

Patrón (Clase Pattern)

Verificador o Encajador (Clase Matcher)

Los metacaracteres son símbolos que tienen un significado diferente a su uso habitual, hemos dicho que si se quiere encontrar la palabra cuerpo podríamos escribirla (eso es literal), pero si escribo * en un patrón estoy buscando desde cero hasta cualquier número de caracteres del patrón especificado en la cadena, de tal manera que si coloco c\\w* en el patrón, se verificará si la cadena contiene una c, luego está seguida por cero o varios caracteres de palabra, de tal manera que coincide con carro, casa, coche y en fin palabras que comienzan por c.

Veamos una lista de los más comunes metacaracteres:

Metacaracteres Generales

Metacaracter

Significa

\

Elimina el significado literal del siguiente carácter siguiente

\t

Tabulador

\n

Nueva línea

\r

Retorno de carro

. (punto)

Un solo character. Ejemplo: “pas.”: coincide con pasa, pase, paso

Metacaracteres de limite

Metacaracter

Significa

Ejemplo

^

Que comience la línea por…

”^h\\w*”: Que la línea comience por la palabra con h. Nota: “^” tiene otro significado dentro de corchetes, ver más adelante

$

Final de línea

”\\w*\\.$”: línea que termina en punto (fin de párrafo), coincide con “palabra.” (palabra punto)

\b

Límite de palabra

Puede ser un espacio o retorno de carro.

\B

Límite de no palabra

Contrario a \b

\A

Comienzo de entrada

\\AH\\w*” coincide con “palabra de inicio de entrada”. “Hola”

Metacaracteres de letras

Metacaracter

Coincide con

\w

Cualquier carácter. Ya hemos dado varios ejemplos de este.

\W

No carácter.

\d

Un dígito (del 0 al 9)

\D

Lo que no sea dígito

\s

Espacio en blanco

\S

Un espacio no en blanco

Las expresiones regulares también permiten hacer coincidir con ciertos caracteres no predeterminados si estos se encierran entre corchete, de la siguiente manera:

[0123456789]: cualquier número, por lo tanto es el equivalente a \d.

[0-9]: igual al anterior pero expresado a manera de intervalo.

pas[ao]:coincide con pasa, paso, pero no con pase (entre corchete los dígitos que pueden coincidir).

Si quiero al contrario que no sea un elemento dentro del corchete se comienza dentro del corchete con circunflejo ^.

Per[^a]: no coincide con pera, pero si con Pero o Perú.

También podemos colocar varios intervalos:

[a-cA-C]: coincide con a, b o c minúsculas o mayúsculas.

La última característica que se verá en este artículo es la capacidad de las expresiones regulares de coincidir con determinado número de caracteres, ya vimos que el asterisco permite coincidir con cero o mas caracteres, veamos otros metacaracteres.

coincide con A cero o mas vences

Metacaracteres Generales

Metacaracter

Coincide con

A*

A cero o más veces

A?

A cero o una vez

A+

A una o más veces

A{n}

A n veces, n es un numero entero

A{n,}

A al menos n veces

A{n,m}

A entre n y m veces, ambos inclusive

Hasta aquí la primera parte del blog, en el siguiente artículo seguiremos hablando se las expresiones regulares y veremos ejemplos de código java.