2012-02-08 27 views
7

Quiero analizar una declaración de declaración de variable y obtener el nombre de la variable. Estoy haciendo el siguienteregex para hacer coincidir la declaración de la variable en java

String var = "private String ipaddress;"; 

I m utilizando el patrón de expresión de abajo para que coincida con la cadena anterior

.*private\\s+([a-z]*)\\s+([a-z0-9_]*); 

No funciona. Dice que no se encontraron coincidencias. ¿Puede alguien ayudarme?

+1

Solo por curiosidad, aunque eso nos permita ayudarlo aún mejor: ¿cuál es el caso de uso para esto? ¿Qué quieres lograr con ese análisis sintáctico? – Thomas

Respuesta

3

.*private\\s+(\\w*)\\s+(\\w*);
utilizan este patrón. [a-z] es una letra minúscula, pero "String" en el texto comienza con mayúscula S. \\w es un personaje de palabra. Es lo mismo que [a-zA-Z0-9_]
Parece que sus textos serán como "private <type> <field name>;" y si es así, su tipo puede contener letras mayúsculas minúsculas, números o subrayados, por lo que escribir \\w es una buena solución.

+1

ligera corrección: la segunda z en su definición de '\ w' debe ser mayúscula :) – Thomas

10

Antes que nada, elimine ese punto del comienzo de la expresión regular, ya que se requiere un carácter antes del private para una coincidencia.

En segundo lugar, su expresión regular distingue entre mayúsculas y minúsculas y no coincidirá con la mayúscula. Utilice [a-zA-Z] o haga que la expresión no sea sensible a mayúsculas y minúsculas ((?i) al inicio IIRC).

Btw, [a-zA-Z0-9_] sería lo mismo que \w.

Otra cosa: su expresión también captaría nombres de variables ilegales y omitirá nombres legales. Las variables no pueden comenzar con un número, pero también pueden contener signos de dólar. Por lo tanto, la expresión del nombre debe ser algo así como ([a-zA-Z_$][\w$]*), lo que significa que el primer carácter debe ser una letra, guión bajo o signo de dólar seguido de cualquier número de caracteres de palabra o signos de dólar.

Una última nota: dependiendo de lo que hagas con esas declaraciones, ten en cuenta que es posible que tengas que comprobar esas palabras reservadas. La expresión ajustada aún coincidiría con "private String private", por ejemplo.

Otra última nota: tenga en cuenta que puede haber más modificadores que private para una variable, p. public, protected, static etc. o ninguno en absoluto.

Edición:

Ahora que tiene el asterisco después del primer punto, que no debería ser un problema para su caso particular. Sin embargo, un punto coincide con casi cualquier carácter y, por lo tanto, también podría coincidir con fooprivate. Dependiendo de lo que quiera lograr, elimine el punto o agregue un \s+ después del .*.

+0

el punto al principio es correcto, ya que va seguido de un' * 'que tampoco coincidirá con la aparición del punto. –

+0

@CarlosHeuberger sí, ahora es algo correcto, aunque coincidiría con 'barprivate' también. Sin embargo, cuando escribí eso, faltaba el asterisco (o al menos no lo vi debido a problemas de formato) :) – Thomas

+0

OK, y una razón más para no usar la expresión regular para analizar ... –

3

debe utilizar esta expresión regular:

^(?s)\\s*private\\s+(\\w+)\\s+(\\w+)\\s*;\\s*$ 

Esto se asegurará de igualar:

  • Coincidencia insensibles a excepción de palabras clave private
  • declaraciones de múltiples líneas
  • espacios en blanco en el arranque, final y en el medio
+0

esto (probablemente erróneamente) debería coincidir con 'PRIVADO ...' –

+0

@CarlosHeuberger: Gracias actualizó la respuesta. – anubhava

5

Desde la declaración de una variable en Java puede tener más de las 3 palabras antes del nombre de la variable, sugeriría no limita su búsqueda y utilizar esto:

String var = "private String ipaddress;"; 
//String var2 = "private static final int test=13;"; 

Pattern p = Pattern.compile(".+\\s(.+?)(;|=)"); 
Matcher m = p.matcher(var); 

while(m.find()){ 
    System.out.println(m.group(1)); 
} 

Se buscará cualquier nombre de variable que comienza con un espacio en blanco y termina con ";" o "=". Esta es una búsqueda más general del nombre de la variable.

EDITAR Éste me hizo pensar en realidad, ya que esta es también la declaración legal en Java:

private 
static 
volatile 
String 
s , t1 = ""; 

En realidad, esto se podría mejorar probablemente como se thinked/hecho rápido.

public static void main(String[] args) { 
String var0 = "private static final int test,test2;"; 
String var1 = "private \n static \n final \n int \n testName \n =\n 5 \n"; 
String var2 = "private \n static \n final \n String \n testName \n =\n \" aaa   = bbbb \" \n"; 
String var3 = "private \n static \n final \n String \n testName,testName2 \n =\n \" aaa   = bbbb \" \n"; 

String var4 = "int i;"; 
String var5 = "String s ;"; 
String var6 = "final String test ; "; 
String var7 = "public int go = 23;"; 
String var8 = "public static final int value,valu2 ; "; 
String var9 = "public static final String t,t1,t2 = \"23\";"; 
String var10 = "public \n static \n final \n String s1,s2,s3 = \" aaa , bbb, fff, = hhh = , kkk \";"; 
String var11 = "String myString=\"25\""; 

LinkedList<String> input = new LinkedList<String>(); 
input.add(var0);input.add(var1);input.add(var2);input.add(var3);input.add(var4);input.add(var5); 
input.add(var6);input.add(var7);input.add(var8);input.add(var9);input.add(var10); 
input.add(var11); 

LinkedList<String> result = parametersNames(input); 
for(String param: result){ 
    System.out.println(param); 
} 

} 

private static LinkedList<String> parametersNames(LinkedList<String> input){ 
LinkedList<String> result = new LinkedList<String>(); 
for(String var: input){ 

    if(var.contains("\n")) var = var.replaceAll("\n", ""); 
    var = var.trim(); 
    if(var.contains("=")){ 
     var = var.substring(0, var.indexOf("=")).trim() + ""; 
     Pattern p = Pattern.compile(".+\\s(.+)$"); 
     Matcher m = p.matcher(var); 

     if(m.find()){ 
     if(m.group(1).contains(",")){ 
      String [] tokens = m.group(1).split(","); 
      for(String token : tokens){ 
      result.add(token); 
      } 
     } else{ 
      result.add(m.group(1)); 
     } 
     } 

    } else{ 
     Pattern p = Pattern.compile(".+\\s(.+?)(;|=)"); 
     Matcher m = p.matcher(var); 

     if(m.find()){ 
     if(m.group(1).contains(",")){ 
      String [] tokens = m.group(1).split(","); 
      for(String token : tokens){ 
      result.add(token); 
      } 
     } else{ 
      result.add(m.group(1)); 
     } 
     } 
    } 
} 

return result; 
} 
3

Eche un vistazo a los patrones de expresiones regulares de Checkstyle para convenciones de nomenclatura (tipos, métodos, paquetes, etc.). Más información here.

Cuestiones relacionadas