RegEx en JavaScript

facebook-svg gplus-svg twitter-svg

Las expresiones regulares son patrones utilizados para encontrar una determinada combinación de caracteres dentro de una cadena de texto. En JavaScript, las expresiones regulares también son objetos.

Crear una nueva expresión regular en JavaScript.

Lo podemos hacer de dos maneras:

1. como una variable donde el patrón de búsqueda aparece entre barras oblicuas:

var reg_ex = /prueba/;

2. como una nueva instancia del objeto RegExp

var reg_ex = new RegExp("prueba");

Métodos que utilizan expresiones regulares:

Estos patrones son utilizados a través de los métodos exec() y test() de RegExp, así como los métodos match(), replace(), search() y split() de String.

Métodos de String
match cadena.match( RegExp ) Busca una coincidencia en una cadena de texto y devuelve un array con información acerca de la coincidencia o null
replace cadena.replace( RegExp , reemplazar); Busca una coincidencia y la reemplaza la con otra cadena de texto
search cadena.search( RegExp ); Busca una coincidencia en una cadena de texto y devuelve la posición de la equivalencia encontrada o -1.
split cadena.split( RegExp ) Método que utiliza otra cadena de texto o una expresión regular para romper una cadena de texto en un array de subcadenas
Métodos de RegExp:
test RegExp.test( cadena ) Comprueba  si hay una coincidencia o no. Devuelve true o false (un booleano)
exec RegExp.exec( cadena ) Busca una coincidencia en una cadena de texto. Devuelve un array con información.

El método match()

El método match() es un método de String que busca una coincidencia en una cadena de texto y devuelve un array con información acerca de la coincidencia encontrada o null.

cadena.match(RegExp);
Ejemplo 1:

La cadena de texto que queremos comprobar es:

var epigrama = "A la abeja semejante, para que cause placer, el epigrama ha de ser: pequeño, dulce y punzante.";

El patrón de búsqueda ( la expresión regular ):

var rex = /[a-z]+/gi;

La expresión regular rex busca cualquier grupo de una o más ( /[a-z]+/gi ) letras de a a z ( /[a-z]+/gi; ) y utiliza dos modificadores ( modifiers o flags ): i ( /[a-z]+/gi; ) que significa que busca tanto mayúsculas como minúsculas ( case insensitive ); y g ( /[a-z]+/gi; ) que quiere decir que es una búsqueda global ( global match ), o sea: no para después de encontrar una primera ocurrencia.

Para sacar en consola el resultado de match() podemos escribir:

console.log(
    epigrama.match(rex)
  );

En este caso el resultado es el array de las ocurrencias encontradas:

["A", "la", "abeja", "semejante", "para", "que", "cause", "placer", "el", "epigrama", "ha", "de", "ser", "peque", "o", "dulce", "y", "punzante"]
Ejemplo 2:

En el caso que no se trate de una búsqueda global ( no utiliza el modificador g ) el resultado es un array que contiene el resultado de la búsqueda y de los grupos ( capturing groups ) del patrón de búsqueda.

// la cadena de texto
var texto = "Mi teléfono es 972.555555";
// el patrón de busqueda
var telRex = /(\d{3})[-.](\d{6})/;

La expresión regular telRex busca un grupo de tres dígitos /(\d{3})[-.](\d{6})/ seguidos por un guion o un punto (/(\d{3})[-.](\d{6})/), seguidos por un grupo de 6 dígitos ( /(\d{3})[-.](\d{6})/ ).

Los grupos de captura ( capturing groups ) son aquellas expresiones regulares que aparecen entre paréntesis. En este caso el patrón de búsqueda tiene dos grupos de captura: el primer grupo de captura: /(\d{3})[-.](\d{6})/ busca 3 dígitos seguidos. El segundo grupo de captura /(\d{3})[-.](\d{6})/ busca 6 dígitos seguidos.

Para sacar en consola el resultado de match() escribimos:

console.log(
    texto.match(telRex)
  );

En este caso el conseguimos un array que contiene el resultado de la búsqueda y de los grupos ( capturing groups ) del patrón de búsqueda:

["972.555555", "972", "555555"]
Ejemplo 3:

Si no hay coincidencia el método match() devuelve null.

console.log(
    epigrama.match(telRex)
);// null

Vea estos ejemplos en codepen.io

El método replace()

El método replace() es un método de String que busca una coincidencia y la reemplaza con otra cadena de texto.

cadena.replace( buscar_RegExp , reemplazar);
Ejemplo 1:

La cadena de texto que queremos comprobar es:

var texto = "A la abeja semejante, para que cause placer, el epigrama ha de ser: pequeño, dulce y punzante.";

El patrón de búsqueda ( la expresión regular ) busca si "abeja" se encuentra en var texto y si encuentra una ocurrencia de "abeja" la reemplaza por "avispa":

var buscar = /abeja/;
var reemplazar = "avispa";
var nuevoTexto = texto.replace(buscar, reemplazar);
console.log(nuevoTexto);

El resultado ( nuevoTexto ) es una nueva cadena de texto donde en lugar de "abeja" aparece "avispa".

"A la avispa semejante, para que cause placer, el epigrama ha de ser: pequeño, dulce y punzante."

La cadena de texto original queda sin cambiar. Lo podemos comprobar sacando en consola la variable texto

console.log(texto);
Ejemplo 2

Si utilizamos el modificador global g ( /\b\w{6,8}\b/g ), podemos reemplazar varias ocurrencias en el texto, por ejemplo podemos reemplazar todas las palabras entre 6 y 8 letras ( /\b\w{6,8}\b/ ) por la palabra "pastelito". El carácter \b ( /\b\w{6,8}\b/g ) marca el principio o el final de una palabra.

console.log(
    texto.replace(/\b\w{6,8}\b/g, "pastelito")
  );

En este caso el resultado es:

"A la abeja semejante, para que cause pastelito, el pastelito ha de ser: pequeño, dulce y pastelito."
Ejemplo 3

Como segundo argumento de replace() podemos utilizar retroreferencias que en este caso dobla la vocal encontrada ( $1$1 ).

Vayamos por partes. El set de caracteres [aeiou] busca una vocal ( o sea: una a o una e o una e o una i o una o u una u) . Los grupos de captura ( capturing groups ) son aquellas expresiones regulares que aparecen entre paréntesis, y pueden ser utilizadas más tarde mediante retroreferencias. En este caso $1 es una retroreferencia que captura el primer grupo (/([aeiou])/g).

console.log(
    texto.replace(/([aeiou])/g, "$1$1")
  );

El resultado de esto es una nueva cadena de texto donde cada vocal aparece dos veces:

"A laa aabeejaa seemeejaantee, paaraa quuee caauusee plaaceer, eel eepiigraamaa haa dee seer: peequueeñoo, duulcee y puunzaantee."
Ejemplo 4

El método replace() puede tomar como segundo argumento una función de retrollamada ( callback function ), que toma como argumento la subcadena encontrada, en este caso una vocal.

console.log(
    texto.replace(/([aeiou])/g, function(encontrado) {
      return "*" + encontrado + "*"
    })
  );

El resultado de esto es una cadena de texto donde cada vocal aparece entre asteriscos.

"A l*a* *a*b*e*j*a* s*e*m*e*j*a*nt*e*, p*a*r*a* q*u**e* c*a**u*s*e* pl*a*c*e*r, *e*l *e*p*i*gr*a*m*a* h*a* d*e* s*e*r: p*e*q*u**e*ñ*o*, d*u*lc*e* y p*u*nz*a*nt*e*."

Puede parecer una tontería poner tantos asteriscos, pero imagínense que en lugar de asteriscos ponemos la vocal encontrada dentro de un elemento <span>. Y podemos vincular al <span> a un evento clic. Y cada vez que alguien hace clic en una a - por ejemplo - esta cambia en una á. Y luego al segundo clic la á cambia de nuevo en una a. Y esto podría ser un ejercicio fantástico para quienes quieren practicar los acentos en español.
Pero lo esencial de todo esto es que podemos utilizar funciones de retrollamada como segundo argumento de replace().

Ejemplo 5

El objeto arguments es una variable local disponible dentro de todas las funciones JavaScript.  El objeto arguments contiene los argumentos de la función. En el siguiente ejemplo quiero recuperar los argumentos de la función anónima, la retrollamada de replace().

La cadena de texto utilizada es:

var telefonos = "Llámame a mi casa 972.555555, o a casa de mis abuelos 977.333333, o incluso a este número 979.223344. También me puedes llamar a 664.333333";

La expresión regular telRex busca un grupo de tres dígitos /(\d{3})\.(\d{6})/ seguidos por un punto (/(\d{3})\.(\d{6})/), seguidos por un grupo de 6 dígitos ( /(\d{3})\.(\d{6})/ ). Observe por favor que el punto va precedido por el carácter de escape ( \ ) ya que los metacaracteres deben ser escapados cuando se utilicen como caracteres normales. El metacarácter punto ( . ) representa a cualquier carácter excepto un salto de línea.

var telRex = /(\d{3})\.(\d{6})/;

A continuación sacamos en consola el resultado de replace(), el objeto Arguments de la función de retrollamada:

telefonos.replace(telRex, function(){  
  console.log(arguments);
});

El resultado de esto es:

Arguments[5]
  0:"972.555555" //la coincidencia encontrada
  1:"972"        //el primer grupo de captura
  2:"555555"     //el segundo grupo de captura
  3:18           //la posición en la cadena de texto
  4:"Llámame a mi casa 972.555555, o a casa de mis abuelos 977.333333, o incluso a este número 979.223344. También me puedes llamar a 664.333333"

La primera propiedad del objeto Arguments es la coincidencia encontrada ( 972.555555 ),
las siguientes dos propiedades son los grupos de captura ( capturing groups ) de la expresión regular utilizada,
la siguiente propiedad es la posición ( 18 ) de la ocurrencia encontrada, y finalmente
la cadena de texto.

Es importante conocer estos argumentos para poder emplearlos debidamente. En el siguiente ejemplo quiero utilizarlos para añadir al texto la provincia correspondiente a cada número de teléfono.

Ejemplo 6

La cadena de texto utilizada es la misma:

var telefonos = "Llámame a mi casa 972.555555, o a casa de mis abuelos 977.333333, o incluso a este número 979.223344. También me puedes llamar a 664.333333";

La expresión regular es casi la misma, solo que esta vez realiza una búsqueda global:

/(\d{3})\.(\d{6})/g;

La función de retrollamada utilizada ( una función anónima ) utiliza una sentencia switch para establecer el nombre de la provincia ( lugar ).

var resultado = telefonos.replace(/(\d{3})\.(\d{6})/g , function(encontrado, grupo1) { 
   var lugar;
   switch (grupo1) {
        case "972":
          lugar = "Girona";
          break;
  
       case "977":
          lugar = "Tarragona"
          break;
  
       case "979":
          lugar = "Palencia"
          break;
  
       default:
          lugar = "España"
      }
      return encontrado + " ( " + lugar + " )"
    })
  console.log(resultado);

El resultado de todo esto es:

"Llámame a mi casa 972.555555 ( Girona ), o a casa de mis abuelos 977.333333 ( Tarragona ), o incluso a este número 979.223344 ( Palencia ). También me puedes llamar a 654.333333 ( España )"

Vea estos ejemplos en codepen.io

El método search() busca una coincidencia en una cadena de texto y devuelve la posición de la equivalencia encontrada o, si no hay coincidencia, devuelve  -1.

cadena.search(regEx)

En este ejemplo la cadena de texto utilizada es:

var cadena = "A la abeja semejante, para que cause placer, el epigrama ha de ser: pequeño, dulce y punzante.";
var rex = /abeja/;
console.log(
    cadena.search(rex)
  );

El resultado en este caso es 5 ( la posición de "abeja" en la cadena de texto var cadena )

Vea estos ejemplos en codepen.io

El método split()

El método split() utiliza una cadena de texto o una expresión regular para romper una cadena de texto dada en un array de subcadenas.

cadena.split(regEx)
Ejemplo 1

La cadena de texto utilizada es la de siempre:

var cadena = "A la abeja semejante, para que cause placer, el epigrama ha de ser: pequeño, dulce y punzante.";

Quiero romper la cadena de texto por los espacios vacíos ( /[,\s]+/ ) o por las comas ( /[,\s]+/ ) entre palabras.

var rex = /[,\s]+/;

var resultado = cadena.split(rex);
  console.log(resultado);

El resultado en este caso es el siguiente array:

["A", "la", "abeja", "semejante", "para", "que", "cause", "placer", "el", "epigrama", "ha", "de", "ser:", "pequeño", "dulce", "y", "punzante."]
Ejemplo 2

En el ejemplo anterior, al final del texto hay un punto que no he tomado en consideración. Y pueden haber otros signos de puntuación, que tampoco he tomado en consideración.
Podría utilizar otro patrón de búsqueda como /[\W]+/ que busca cualquier carácter NO alfanumérico.

var reg_ex = /[\W]+/;

var resultado = cadena.split(reg_ex);
console.log(resultado);

En este caso el resultado es:

["A", "la", "abeja", "semejante", "para", "que", "cause", "placer", "el", "epigrama", "ha", "de", "ser", "peque", "o", "dulce", "y", "punzante", ""]
Ejemplo 3

Parece bien pero hay un problema: resulta que los diacríticos como ñ de pequeño no son caracteres alfanuméricos, y la palabra "pequeño" aparece rota en "peque" y "o". La solución es utilizar el siguiente patrón de búsqueda:

var reg_ex = /[^a-z0-9\u00C0-\u017F]+/;

O sea: quiero romper la cadena de texto por uno o más caracteres ( /[^a-z0-9\u00C0-\u017F]+/ ) que NO sea ( /[^a-z0-9\u00C0-\u017F]+/ ) una letra de a a z ( /[^a-z0-9\u00C0-\u017F]+/ ) NI un digito de 0 a 9 ( /[^a-z0-9\u00C0-\u017F]+/ ) NI un diacrítico ( /[^a-z0-9\u00C0-\u017F]+/ ):

var reg_ex = /[^a-z0-9\u00C0-\u017F]+/;
var palabras = cadena.split(reg_ex);
console.log(palabras);

Ahora el resultado es:

["A", "la", "abeja", "semejante", "para", "que", "cause", "placer", "el", "epigrama", "ha", "de", "ser", "pequeño", "dulce", "y", "punzante", ""]

Mucho mejor.

Ejemplo 4

Sería interesante poder recuperar la puntuación y los espacios vacíos entre palabras, por tal de poder restaurar la frase después de manipularla. Si ponemos la expresión regular dentro de un grupo de captura ( dentro de paréntesis ) podemos recuperar tanto a las palabras cómo a los espacios y a la puntuación.

var reg_ex1 = /([^a-z0-9\u00C0-\u017F]+)/i;
var palabras = cadena.split(reg_ex1);
console.log(palabras);

El resultado de todo esto es el siguiente array:

["A", " ", "la", " ", "abeja", " ", "semejante", ", ", "para", " ", "que", " ", "cause", " ", "placer", ", ", "el", " ", "epigrama", " ", "ha", " ", "de", " ", "ser", ": ", "pequeño", ", ", "dulce", " ", "y", " ", "punzante", ".", ""]

Ahora podemos iterar este array y poner cada elemento dentro de un elemento <span>.

var nuevaCadena = "";
  for( var i = 0; i < palabras.length; i++){
    nuevaCadena += "<span>"+palabras[i]+"</span>";
  }
var parafo = document.querySelector("p")
parafo.innerHTML = nuevaCadena;

De esta manera, no solo he recuperado la frase inicial, sino que tengo cada palabra, cada coma, cada espacio, dentro de un elemento <span> que puedo manipular. Por ejemplo puedo vincular al <span> un evento mouseover y un evento mouseout, y cada vez que el usuario pasa por encima de cada palabra, algo pasa con ella:

Veamos un ejemplo:


var cadena = "A la abeja semejante, para que cause placer, el epigrama ha de ser: pequeño, dulce y punzante.";
var reg_ex1 = /([^a-z0-9\u00C0-\u017F]+)/i;
var palabras = cadena.split(reg_ex1);

var nuevaCadena = "";
for (var i = 0; i < palabras.length; i++) {
  nuevaCadena += "" + palabras[i] + "";
}

var parafo = document.querySelector(".frase")
parafo.innerHTML = nuevaCadena;

var spans = parafo.querySelectorAll("span");
for (var i = 0; i < spans.length; i++) {
  (function(i) {
    spans[i].addEventListener("mouseover", function(evt) {
      this.style.backgroundColor = "gold";
    }, false);
    spans[i].addEventListener("mouseout", function(evt) {
      this.style.backgroundColor = "transparent";
    }, false);
  }(i));
}

Por favor pase con el ratón por encima de la siguiente frase:

O vea todos estos ejemplos en codepen.io

El método test()

El método test() es un método de RegExp que busca una coincidencia en una cadena de texto y devuelve true ( verdadero ) o false ( falso ).

var reg_ex = /^\d{3}$/;
var cadena = "444";
console.log(
  reg_ex.test(cadena);
)

En este caso el resultado es true.

Vea este ejemplo en codepen.io

El método exec()

El método exec() es un método de RegExp que busca una coincidencia en una cadena de texto y devuelve el array de los resultados.

reg_ex.exec(cadena);
Ejemplo 1

La cadena de texto utilizada es:

var cadena = "los teléfonos son: 972.345678 y 930.505050.";

La expresión regular busca un grupo de tres dígitos /(\d{3})[-.](\d{6})/ seguidos por un guion o un punto ( /(\d{3})[-.](\d{6})/ ), seguidos por un grupo de 6 dígitos ( /(\d{3})[-.](\d{6})/ ).

var reg_ex = /(\d{3})[-.](\d{6})/;

A continuación utilizamos el método exec() y sacamos el resultado en consola:

var resultado = reg_ex.exec(cadena);
console.log(resultado);

En este caso el resultado es:

0: "972.345678"
1: "972"
2: "345678"
index: 19
input: "Los telefonos son: 972.345678 y 930.505050."
length: 3

- El primer elemento del array resultado representa la coincidencia encontrada:0: "972.345678"
- Los siguientes dos elementos representan los dos grupos de captura de la expresion regular 1: "972", 2: "345678"
- El cuarto elemento ( index ) representa la posición de la la coincidencia encontrada ( 19 en este caso )
- El último elemento ( input ) representa la cadena de texto original 1: "input: "Los telefonos son: 972.345678 y 930.505050.""

Sabiendo todo esto podemos facilmente utilizar el rezultado para hacer cosas interesantes.

Ejemplo 2

A diferencia del ejemplo anterior la expresión regular utiliza el modificador global ( g ), o sea: en lugar de un solo array obtenemos varios arrays de los resultados.

var reg_ex_global = /(\d{3})[-.](\d{6})/g;
var resultados = reg_ex_global.exec(cadena);
while(resultados !=null){
  console.log(resultados);
  resultados = reg_ex_global.exec(cadena);
}

En este caso el resultado es:

["972.345678", "972", "345678"]
["930.505050", "930", "505050"]

Vea estos dos ejemplos encodepen.io