domingo, 1 de febrero de 2009

Expresiones regulares extendidas

Los sistemas UNIX actuales admiten extensiones a las expresiones regulares básicas:
  • debemos usar egrep, grep -E, sed -r
ER concuerda con
+ una o más ocurrencias de la RE anterior
? cero o una ocurrencia de la RE anterior
Además, \( \) y \{ \} se reemplazan por ( ) y { }
  • Ejemplos:
    • ab+c concuerda con abc, abbc, pero no con ac
    • ab?c concuerda con ac, abc, pero no con abbc
  • Para usar los caracteres (, ), { o } escaparlos con \

Alternancia

El carácter | permite alternar entre 2 o más RE
  • (a|b)c concuerda con ac o bc

Etiquetado

Las RE que se ponen entre ( ) quedan etiquetadas, y podemos hacer referencia a esos elementos mediante \n, con n el número de la etiqueta
  • Ejemplos:
    • (.)oo\1 concuerda con moom, noon, pero no con moon
    • (.)oo\1-(.)aa\1\2 concuerda con moom-paamp

Otros caracteres

Además de los ya vistos, pueden usarse otros metacaracteres:
ER concuerda con
\n, \r, \t LF, CR y tab (no siempre funcionan)
[:space:] caracteres en blanco ([ \t\n\r\f\v])
[:blank:] espacio y tabulado
[:alnum:] o \w caracteres alfánuméricos (letras y números)
[:digit:] dígitos
[:alpha:] alfabéticos
[:upper:] mayúsculas
[:lower:] minúsculas
[:xdigit:] dígitos hexadecimales
[:punct:] signos de puntuación
[:cntrl:] caracteres de control
[:graph:] caracteres imprimibles (sin espacio)
[:print:] caracteres imprimibles (con espacio)
\<, \> inicio/fin de palabra
\b posición entre palabras
\B posición en medio de una palabra
  • [[:upper:]]bc concuerda con Abc, pero no abc
  • \babc\b concuerda con ab abc df, pero no con abcdef
  • \Babc\B concuerda con ababcdf, pero no con ab abc df

Más ejemplos

  1. \w+@\w+\.\w+((\.\w+)*)? concuerda con direcciones de e-mail
  2. (0[1-9]|[12][0-9]|3[01])-(0[1-9]|1[012])-(19|20)[0-9]{2} concuerda con fechas en el formato dd-mm-yyyy (años entre el 1900 y 2099)
  3. [-+]?([0-9]*\.)?[0-9]+([eE][-+]?[0-9]+)? concuerda con números en punto flotante (con o sin exponente)

Ejemplos de uso con sed:

$ echo "abc1234def" | sed -r "s/[0-9]+/NUMERO/"
abcNUMEROdef
$ echo "abc1234def" | sed -r ´s/[0-9]+/<&>/´
abc<1234>def
# En el siguiente ejemplo, notar que las ER intentan siempre reconocer la secuencia más larga posible
$ echo "000x111x222x333" | sed ´s/x.*x/<&>/´
000333
# Eliminar blancos a principio y al final de línea y sustituir más de un blanco seguido por uno solo
$ sed -r "s/^_+// ; s/_+$// ; s/__+/_/g" fich
# Pon los 4 primeros caracteres de cada línea al final de la misma
$ sed -r ´s/^(.{4,4})(.*)/\2\1/´ fich
# Cambia de minúsculas a mayúsculas la primera letra de cada palabra
$ sed -r ´s/\<./\u&/g´
# Convierte DOS newlines (CR/LF) a formato Unix (LF)
$ sed ´s/^M$//´4
# también funcionaría
$ sed ´s/\r//´