El difícil arte de las expresiones regulares

Hace poco surgió en el foro una situación particular donde un usuario tiene un texto donde se intercalan entre paréntesis una mezcla de texto y números. El usuario quería encontrar solo los elementos que tuvieran texto y números, no los que tuvieran solo texto o solo números. Por ejemplo, encontrar

  • (20 años)
  • (2 años)
  • (los años 20)
  • (a los 20 años)
  • (en 20 o 30 años)

pero no

  • (20)
  • (un texto)

La expresión regular que se me ocurrió fue

\([^\(]+[:digit:]+[^\(]+\)

La interpretación de esta expresión es la siguiente: un paréntesis de apertura, uno o más caracteres que no nos un paréntesis de apertura, uno o más dígitos, uno o más caracteres que no son un paréntesis de apertura, un paréntesis de cierre.

Pero esta expresión falla en encontrar el segundo ejemplo (2 años) ya que la expresión [^\(]+ (uno o más caracteres que no sean un paréntesis de apertura) encuentra también el 2 por lo que la expresión [:digit:]+ ya no encontrará nada.

Por otra parte, la expresión

\([:digit:][^\([:digit:]]+\)

encontrará cadenas del tipo (2 años)… pero fallará con las otras. Su interpretación es la siguiente: un paréntesis de apertura, un dígito, uno o más caracteres que no son ni un paréntesis de apertura ni un dígito, un paréntesis de cierre.

¿Entonces?

Pues recordar que la barra vertical sirve para establecer una opción del tipo esto|aquello:

\([:digit:][^\([:digit:]]+\)|\([^\(]+[:digit:]+[^\(]+\)

funciona perfectamente, aunque debo admitir que es la expresión regular más larga que jamás he escrito…

Por supuesto, tienen más sobre expresiones regulares en el correspondiente capítulo de mi libro.

Anuncios

  1. #1 por Oliver Leuyim Angel el 10 julio, 2013 - 22:01

    Así es, el arte de las expresiones regulares es algo magnificado con su grado de complejidad.

    Para el asunto que hablas en el tema, puede ser también una solución esta expresión:

    \(.*\)

    Por el lado que yo veo es que aquí encuentra todo no importa que carácter o tipo de carácter sea, lo encuentra, y en la que sugieres que es mas compleja y dedicada.

    Aveces reflexiono con que las expresiones regulares son mucho como la programación, aveces se hacen códigos muy largos cuando se pueden simplificar en unas pocas lineas todo inicia en la prospección de lo deseado y en su proceso y diagrama de flujo.

    En si es muy buena tu aportación y se te agradece muchísimo, excelente que vivan personas como tu.

    gracias.

A %d blogueros les gusta esto: