2009-09-04 9 views
14

Tengo algunas expresiones regulares complejas que debo comentar para la legibilidad y el mantenimiento. La especificación de Java es bastante escueta y he luchado durante mucho tiempo para que funcione. Finalmente me quedé sin error y se publicará como una respuesta pero estaría agradecido por cualquier otro consejo sobre expresiones regulares que mantienenIncluyendo comentarios en expresiones regulares de Java

Como ejemplo quiero comentar los subcomponentes (de los patrones) en un nombre analizador simple:

String testTarget = "Waldorf T. Flywheel"; 
    String patternS = "([A-Za-z]+)\\s+([A-Z]\\.)?\\s+([A-Za-z]+)"; 
    Pattern pattern = Pattern.compile(patternS, Pattern.COMMENTS); 
    Assert.assertTrue(pattern.matcher(testTarget).matches()); 

EDITAR: Estaría agradecido por los ejemplos del formato (? X) también.

EDITAR: @ ​​geowa4 tiene una buena sugerencia que evita los comentarios incrustados. Sinnce Java y otros han proporcionado comentarios incrustados, ¿cuáles son los casos en que son útiles? (Creo que tengo un caso, pero me gustaría ver a otros).

EDIT: Como se señala más adelante @mikej la expresión regular no admite el pozo inicial opcional y sería mejor como:

 String patternS = "([A-Za-z]+)\\s+([A-Z]\\.\\s+)?([A-Za-z]+)"; 

pero que terminaría la extracción de espacio en la inicial

Respuesta

21

Ver el mensaje por Martin Fowler en ComposedRegex para más ideas sobre cómo mejorar la legibilidad de expresiones regulares. En resumen, recomienda desglosar una expresión regular compleja en partes más pequeñas a las que se les puedan dar nombres de variables significativos. p.ej.

String mandatoryName = "([A-Za-z]+)"; 
String mandatoryWhiteSpace = "\\s+"; 
String optionalInitial = "([A-Z]\\.)?"; 
String pattern = mandatoryName + mandatoryWhiteSpace + optionalInitial + 
    mandatoryWhiteSpace + mandatoryName; 
+0

Gracias - este es un enfoque útil. También apuntó a otra idea de usar lenguajes específicos de dominio para generar expresiones regulares (http://flimflan.com/blog/ReadableRegularExpressions.aspx). (Esto es realmente lo que hago en mi aplicación, que tiene combinaciones complicadas de expresiones regulares compuestas para datos científicos, pero eso está fuera del alcance de esta pregunta). –

+1

Esta es una solución muy limpia y ordenada. Aunque opcionalWhiteSpace probablemente debería ser obligatorioWhiteSpace? :) – crunchdog

+0

Gracias crunchdog. Creo que lo que me sorprendió es que hay una limitación en el patrón en el OP en que si tenemos un nombre sin la inicial del segundo nombre, como Fred Bloggs, entonces necesitamos 2 espacios entre el nombre y el apellido para que coincida con los dos \ \ s + en el patrón. Estaba tratando de abordar esto, pero por ahora he editado la respuesta para que el patrón sea equivalente al que está en el PO. – mikej

11

encontré la trabajado siguientes:

 String pattern2S = 
      "([A-Za-z]+)  # mandatory firstName\n" + 
      "\\s+    # mandatory whitespace\n " + 
      "([A-Z]\\.)?  # optional initial\n" + 
      "\\s+    # whitespace\n " + 
      "([A-Za-z]+)  # mandatory lastName\n"; 

la clave era incluir el carácter de nueva línea \ n explícitamente en la cadena

15

¿Por qué no acaba de hacer esto:

String pattern2S = 
    "([A-Za-z]+)" + // mandatory firstName 
    "\\s+" +  // mandatory whitespace 
    ...; 

CONTINUACIÓN:

Si desea mantener los comentarios con el patrón y hay que leerlo desde un archivo de propiedades, utilice la siguiente:

pattern=\ 
#comment1\\n\ 
(A-z)\ 
#comment2\\n\ 
(0-9) 
+0

Buena sugerencia. Esto funcionaría en muchos casos simples, pero quiero que las expresiones regulares sean independientes del código en el que se usan (por ejemplo, en archivos de datos externos). Los comentarios en línea seguirán siendo visibles. –

Cuestiones relacionadas