Expresiones regulares

Crear RegEx

Haremos:

> var patron = /pat[aeo]/;
undefined

o:

> var patron = new RegExp(“pato”);

Advertencia

cuando se usa RegExp, el carácter \ se representa mediante “\\”.

¿Contiene una cadena la expresión regular?:

> var a = /abc/
undefined
> a.test("holabcaro")
true

Mini recordatorio de RegEx

Por ejemplo:

/[0-9]/       // Cualquier número
/[aoc]/       // Las letras 'a', 'o', 'c'
/\d/          // Any digit character
/\w/          // An alphanumeric character (“word character”)
/\s/          // Any whitespace character (space, tab, newline, and similar)
/\D/          // A characters that is not a digit
/\W/          // A non-alphanumeric character
/\S/          // A non-whitespace character
/./           // Any character except for newline
/[^01]/       // Cualquier carácter excepto 0 ó 1.
/\d+/         // Uno o más dígitos
/\d*/         // 0 o más dígitos
/casas?/      // 0 o 1 's'.
/\d{1,2}/     // 1 ó 2 dígitos
{,5}          // De 0 a 5 veces
{5,}          // 5 o más veces
/ca(ro)+/     // Agrupa "ro". Acepta: "ca" ó "caro"
/Hola/i       // Insensible al caso
/^\d+$/       // Comienzo y fin de cadena.
/(gato|pez)/  // Machea: gato o pez.
/.../g        // Reemplaza todo cuando se usa con replace.

Advertencia

“w” no captura caracteres internacionales.

Match

Devuelve lo que encuentra:

> /\d+/.exec("Las edades son 33, 25 y 48.")
[ '33',
  index: 15,
  input: 'Las edades son 33, 25 y 48.' ]
> "Las edades son 33, 25 y 48.".match(/\d+/)
[ '33',
  index: 15,
  input: 'Las edades son 33, 25 y 48.' ]

Cuando hay grupos, aparece el match completo y después el de cada grupo:

> "Las edades son 33, 25 y 48.".match(/a(d+)e(s+)/)
[ 'ades',
      'd',
      's',
      index: 6,
      input: 'Las edades son 33, 25 y 48.' ]

lastIndex

No existe una forma adecuada de decir “busca desde”. Como alternativa, podemos hacer:

> var pattern = /y/g;
undefined
> pattern.lastIndex = 3
3
> pattern.exec("xyzzy");
[ 'y', index: 4, input: 'xyzzy' ]

Es un uso “visioso” de:

> var pattern = /y/g;
undefined
> pattern.exec("xyzzy");
[ 'y', index: 1, input: 'xyzzy' ]
> pattern.exec("xyzzy");
[ 'y', index: 4, input: 'xyzzy' ]
> pattern.exec("xyzzy");
null

Replace

Hacemos:

> "papa".replace("p","m")
'mapa'

pero el primer argumento puede ser una expresión regular:

> "paco".replace(/[ao]/,"e")
'peco'
> "paco".replace(/[ao]/g,"e")
'pece'

Nota

no existe un “replaceAll”. Usaremos /.../g.

La potencia aquí reside en la capacidad de backtracking:

> "Garcia Perez, Jose\nPerez, Maria Luisa".replace( /([\w ]+), ([\w ]+)/g, "$2 $1" )
'Jose Garcia Perez\nMaria Luisa Perez'

Podríamos usar $& para la cadena completa.

La segunda parte de replace admite una función:

> "the cia and fbi".replace(/\b(fbi|cia)\b/g, function(str) { return str.toUpperCase();});
'the CIA and FBI'

Boundary Markers

Mediante \b (límite de palabra).

Greedy

(+, *, ?, and {}): son greedy

(+?, *?, ??, {}?): se convierten en non-greedy.

Ejemplo de grupos

Convertir una cadena de texto en fecha:

> function findDate(string) {
    var dateTime = /(\d{1,2})-(\d{1,2})-(\d{4})/;
    var match = dateTime.exec(string);
    return new Date(Number(match[3]),
                    Number(match[2]),
                    Number(match[1]));
  }
 > console.log(findDate("30-1-2003"));
 Sun Mar 02 2003 00:00:00 GMT+0100 (CET)

Uso

Ejemplo:

<script>
var patron = /pat[ao]{2}/;
document.write(“patopata”.search(patron));
document.write(“patoa”.search(patron));
patron = /(pat[ao]){2}/;
document.write(“patopata”.search(patron));
document.write(“patoa”.search(patron));
</script>

Otros elementos a tener en cuenta son:

  • \d un dígito. Equivale a [0-9]
  • \D cualquier caracter que no sea un dígito.
  • \w Cualquier caracter alfanumérico. Equivalente a [a-zA-Z0-9_].
  • \W cualquier caracter no alfanumérico
  • \s espacio
  • \t tabulador