Expresiones regulares en javacript. Teoría y ejemplos

El siguiente artículo es una adaptación de uno de los capítulos de expresiones regulares del libro de O’reilly Javascript Cookbook. Por lo que algunos nombres, y ejemplos de frases los he conservado en inglés. También he eliminado algunas secciones, en este artículo tan sólo se conservar al rededor de 1/3 de todo el contenido original, conservando la teoría más básico y algunos ejemplos prácticos.

Introducción

Las expresiones regulares son patrones de búsqueda que se pueden utilizar para encontrar el texto que coincide con un patrón determinado. Por ejemplo, en el último capítulo, buscamos la  subcadena Cookbook dentro de una cadena más larga:

var testValue = "This is the Cookbook's test string";
var subsValue = "Cookbook";

var iValue = testValue(subsValue); 

devuelve el valor 12 que es el indice de la subcadena

Este fragmento de código funcionó porque estábamos buscando una coincidencia exacta. Pero lo que si queremos una búsqueda más general? Por ejemplo, queremos buscar para Cook y la palabra Book, en cadenas como “Joe’s Cooking Book” o “JavaScript Cookbook”?

Cuando estamos en busca de cadenas que coinciden con un patrón en lugar de una cadena exacta, tenemos que usar expresiones regulares.
Podemos tratar de hacerlo con las funciones de String funciones, pero al final, es realmente fácil de usar expresiones regulares, aunque la sintaxis y el formato es un poco extraño y no necesariamente “amigable”.

Una expresion regular literal

RegExp puede ser un literal y un objeto. Para crear un literal RegExp, se utiliza la siguiente sintaxis:

var re = /regular expression/;

El patrón de expresión regular se encuentra entre la apertura y el cierre de las barras diagonales. Tenga en cuenta que este modelo no es una cadena: no desea utilizar comillas simples o dobles alrededor del patrón, a menos que las propias citas son parte de la estructura de partido.

Las expresiones regulares se componen de caracteres, ya sea solo o en combinación con caracteres especiales, que proporcionan para ajustar más complejo. Por ejemplo, la siguiente es una expresión regular para un patrón que coincida con una cadena que contiene la palabra Shelley y la palabra Powers, en ese orden y separados por uno o más espacios en blanco:

var re = /Shelleys+Powers/;

Los caracteres especiales en este ejemplo son la barra invertida (), que tiene dos fines: o bien se utiliza con un carácter regular, para indicar que se trata de un carácter especial, o se usa con un carácter especial, como el signo más (+ ), para indicar que el caracter debe ser tratada literalmente. En este caso, la barra invertida se utiliza con “s”, que transforma la letra s de un carácter especial la designación de un espacio en blanco, como un espacio, tabulación, avance de línea, etc. El carácter especial s es seguido por el signo más, s+, que es una señal para que coincida con el carácter anterior (en este ejemplo, un espacio en blanco) una o más veces. Esta expresion regular funcionará con:

Shelley Powers

Pero también con la siguiente cadena

Shelley     Powers

No funcionará con el siguiente texto

ShelleyPowers

No importa la cantidad de espacio en blanco entre Shelley y Powers, por el uso de s+. Sin embargo, el uso del signo más se requieren por lo menos un espacio en blanco.

A continuación una tabla con la mayoría de los caracteres especiales en las aplicaciones de JavaScript.

Caracteres especiales para las expresiones regulares con Javascript
Caracter Coincidencia/Patrón Ejemplo
^ Busca la coincicencia al inicio de la cadena /^Esto/ coincidiría en: “Esto es una cadena”
$ Coincidencia con el final del input o del texto /final?/ coincidiría con: “Esto es el final”
* Coincide ninguna o muchas veces /mi*/ coincidiría con: “miiiii” y tambien con “mi”
? Coincide cero o una vez /ap?/ coincidiría con: “apple”
+ Coincide una o muchas veces /ap+/ coincidiría con: “apple”
{n} Coincidiría exactamente n veces /ap{2}/ coincidiría con: “apple” pero no con “apie”
{n,} Coincidiría n o mas veces /ap{2,}/ coincidiría con todas las p en: “apple” y “appple” pero no en “apie”
{n,m} Coincidiría al menos n y como máximo m veces /ap{2,4}/
. Para cualquier caracter salvo salto de linea /a.e/ coincide con “ape” y “axe”
[…] Cualquier caracter dentro de los parentesis /a[px]e/ coincidiría “ape” y “axe” pero no “ale”
[^…] Cualquier caracter menos los que están entre paréntesis /a[^px]/ coincidiría “ale” pero no “axe” o “ape”
b Coincide con el primer límite de la palabra /bno/ coincidiría con el primer “no” en la palabra “nono”
B Coincide con el último límite de la palabra /Bno/ coincide con el ultimo “no” en “nono”
d Para dígitos de 0 a 9 /d{3}/ coincide 123 en “Now in 123”
D Cualquier caracter no digito /D{2,4}/ coincide con “Now ” en “Now in 123”
w Cualquier caracter que sea una letra, digito o barra baja
W Lo contraio a lo anterior /W/ Coincidiría “%” en “100%”
n Para los saltos de linea
s Un solo espacio en blanco
S Un solo caracter pero que no sea un espacio en blanco
t Una tabulacion
(x) paréntesis de captura Recuerda los caracteres coincidentes

Una expresión regular con Object

La expresión regular es un objeto de JavaScript, así como un literal, por lo que también se pueden crear con un constructor, de la siguiente manera:

var re = new RegExp("Shelleys+Powers");

Cuándo usar cada tipo? El literal RegExp se compila cuando el script se evalúa, por lo que debe utilizar un literal RegExp cuando sabes que la expresión no va a cambiar. Una versión compilada es más eficiente. Utilice el constructor cuando cambia la expresión o se va a construir o asignar en tiempo de ejecución.

Ejemplo: Probar si existe una cadena

Vamos a comprobar si una cadena está contenida en otra cadena.
Utilizar una expresión regular JavaScript para definir un patrón de búsqueda, y luego aplicar el patrón contra de la cadena a buscar, mediante el método RegExp. Haremos que coincida con cualquiera cadena que tenga las dos palabras Cook y Book en ese orden:

Solución.

var cookbookString = new Array();

cookbookString[0] = "Joe's Cooking Book";
cookbookString[1] = "Sam's Cookbook";
cookbookString[2] = "JavaScript CookBook";
cookbookString[3] = "JavaScript BookCook";

// patrón de búsqueda
var pattern = /Cook.*Book/;
for (var i = 0; i < cookbookString.length; i++)
alert(cookbookString[i] + " " + pattern.test(cookbookString[i]));

La primera y tercera cadenas tiene un resultado positivo, mientras que la segundo y cuarta no.

El método de prueba RegExp toma dos parámetros: la cadena de prueba, y un modificador opcional. Se aplica la expresión regular con la cadena y devuelve true si hay una coincidencia, falso si no hay.

En el ejemplo, el patrón es la palabra Cook y la palabra Book, que aparecen en algún lugar en la cadena, la palabra Book después de la palabra Cook. Puede haber el númro de caracteres que sea entre las dos palabras, incluyendo que no haya nada indicados por los carácteres espciales, punto (.) y el asterisco (*)

El decimal en las expresiones regulares es un carácter especial que coincide con cualquier carácter excepto el carácter de nueva línea. En el patrón de ejemplo, el decimal es seguido por un asterisco, que coincide con el carácter anterior cero o más veces. Combinados, generan un patrón de coincidencia con cero o más de cualquier carácter, excepto una línea nueva.

Ejemplo: Comprobando las coincidencias entre mayúsculas – minúsculas en una cadena

Quieres comprobar si una cadena está contenida en otra cadena, pero no importar si el caracter mayuscula-minuscula.
Para ello, a la hora de crear la expresion regular, hay que utilizar el indicador para ignorar (i) al final de la expresion regular.

var cookbookString = new Array();

cookbookString[0] = "Joe's Cooking Book";
cookbookString[1] = "Sam's Cookbook";
cookbookString[2] = "JavaScript CookBook";
cookbookString[3] = "JavaScript cookbook";
// patrón de busqueda
var pattern = /Cook.*Book/i;
for (var i = 0; i < cookbookString.length; i++) {
alert(cookbookString[i] + " " + pattern.test(cookbookString[i],i));
}

Los cuatro patrones coindicen.

Flags o indicadores de las expresiones regulares

Flag Significado
g Coincidencia global: comprueba en toda la cadena, en lugar de detenerse cuando encuentra la primera coincidencia.
i ignora el caso
m Se aplica comenzar y terminar la línea de caracteres especiales (^ y $, respectivamente) a cada línea en una cadena de varias líneas

Ejemplo: Encontrar y destacar todas las instancias de un patrón

Quieres encontrar todas las instancias de un patrón dentro de una cadena. Para ello hay que utilizar el método exec en la expresión regular con el flag (g).
Vamos a decir como ejemplo cualquier palabra que empieza con t y termina con e y nos dará igual el numero de caracteres entre ellos.

var searchString = "Now is the time and this is the time and that is the time";
var pattern = /tw*e/g;
var matchArray;

var str = "";
while((matchArray = pattern.exec(searchString)) != null) {
  str+="at " + matchArray.index + " we found " + matchArray[0] + "
";
}
document.getElementById("results").innerHTML=str;

El metodo exec de la expresion regular, devuelve null si no se encuentra la coincidencia, o un array con la información encontrada. En el array se encuentra el valor actual que ha encontrado, el índice de la cadena donde se encuentra la coincidencia,cualquier coincidencias de subcadenas entre paréntesis, y la cadena original.

Ejemplo: Reemplazar un patrón por una nueva cadena

Para ello hay que usar el metodo replace del objeto String con una expresión regular.

var searchString = "Now is the time, this is the time";
var re = /tw{2}e/g;
var replacement = searchString.replace(re, "place");
alert(replacement); // Now is the place, this is the place

Ejemplo: Intercambio de palabras en una cadena usando paréntesis de captura

Hay que usar paréntesis de captura y una expresión regular para encontrar y recordar los dos nombres de la cadena, y revertirlos.

En el ejemplo vamos a intercambiar el nombre de orden, poniendo el nombre al final y el apellido primero.


var name = "Pedro Ventura";
var re = /^(w+)s(w+)$/;
var newname = name.replace(re,"$2, $1");

Los paréntesis de captura nos permitirá no sólo para que coincida con los patrones preestablecidos en una cadena, sino que además hace referencia al subcadenas coincidentes. Las cadenas coincidentes son referenciadas numericamente de izquierda a derecha y son representadas con el uso de “$1” y “$2” en el método replace de String.

Como las dos palabras están separadas por un espacio, es facil de crear la expresión regular, que recoge el nombre (las dos palabras), y el nombre será accesible usando “$1” y el apellido con “$2”.

Patrones especiales para String.replace
Patrón Propósito
$$ Permite remplazar literalmente el signo dolar($)
$& Inserta la subcadena coincidente
$` Inserta parte de la cadena antes de la coincidencia
$’ Inserta parte de la cadena después de la coincidencia
$n Inserta todos los valores capturados por parentesis en la expresión regular.

Ejemplo: Reemplazar HTML Tgas por sus respectivas entidades

A modo simple, convertiremos los guiones de las etiquetas (<>) en sus rectivas entidades &lt;&gt;

var pieceOfHtml = "<p>This is a <span>paragraph</span></p>";
pieceOfHtml = pieceOfHtml.replace(/</g,"&lt;");
pieceOfHtml = pieceOfHtml.replace(/>/g,"&gt;");
document.getElementById("searchResult").innerHTML = pieceOfHtml;

Añado el siguiente enlace http://xregexp.com/ que es una librería de expresiones regulares en javascript bastante buena.

14 opiniones en “Expresiones regulares en javacript. Teoría y ejemplos”

  1. Hola,

    Una pregunta, ¿Como es una expresión regular que soporte acentos, signos de pregunta, signos de exclamaxión, coma, punto y coma, espacio, acentos, punto, dos puntos, y paréntesis?

    Gracias.

    1. Pues tendrías que escapear cada uno de esos caracteres con la barra invertida “”.

      A ver y sobre como seria una expresión regular con todo eso, pues así no se pregunta, necesitas un patrón para crear una expresión regular. Asi que así sin especificar nada en concreto pues te puedo decir que sería algo así

      RegExp.escape = function(text) {
          return text.replace(/[-[]{}()*+?.,\^$|#s]/g, "\$&");
      }
      
  2. Muchas gracias por tu ayuda.
    Quisiera saber como seria el codigo para reemplazar en un string :
    espacio+_ o viceversa=_
    mas de un espacio continuo=un solo espacio
    espacio+ o viceversa=
    espacio+- o viceversa=-
    espacio +) o ( y viceversa=) o (
    y de ser posible hacerlo con un solo patron.
    Gracias.

  3. Saludos con este código logro validar que el usuario introduzca sus dos nombres pero no deja ingresar acentos como puedo hacerlo.

    var frase= /w+s+w+/;

    var Nombre_= eliminaEspacios(document.getElementById(‘txtNombre’).value);

    if (frase.test(Nombre_)){
    alert(“Nombre Bueno”)
    }else{
    alert(“Nombre Malo”)
    }

    }

  4. Buen post! me ha hecho ganar tiempo!!
    En agradecimiento te corrijo un error en el Ejemplo: Encontrar y destacar todas las instancias de un patrón.
    Se te olvidó escapar el carácter reservado “w”. Para que funcione el ejemplo el patrón debería ser:
    var pattern = /t\w*e/g;

    Gracias otra vez!

  5. Necesito que un input text acepte el 1er caracter como número, y los siguientes tres caracteres como letras en minúscula. Sé que esto se hace así: /^[0-9]{1}[a-z]{3}$/

    No quiero que cuando yo teclee una letra me mande un alert diciéndome que no se vale que yo meta letra. ¡No! ¡Eso lo puedo hacer yo! Quiero que el input no me deje escribir una letra como 1er caracter, ni un número después del 1er caracter. Es decir, que aunque yo muela a golpes mi teclado alfabético, el input no muestre una letra como primer caracter!

    De ser posible, pon un ejemplo completo sólo para copiar y pegar. No sólo la idea general.

  6. Como todos los programadores
    mejor deja cosas hechas
    practicas
    regex para nombre en español

    regex para email

    y asi … porfas

    clasifica en dos
    Extraer – Validar
    casos practicos

    Grx

  7. Hola, tengo un problema. Tengo una expresion regular de este estilo,
    /((\d)+)(\s(\d)+){3}/ Yo deseo que el usuario solo me pueda escribir cuatro numeros separados por espacios, esta expresion funciona pero me deja seguir escribiendo ejemplo: 12 12 12 12 es valido, pero 12 12 12 12 12 es invalido y sin embargo me deja, no se porque no me funciona el {3}. Gracias de antemano.

  8. Hola,
    tengo esto para obtener el valor de un parámetro de la url:
    (location.search.match(RegExp(“[?|&]mpInputSearch=(.[^&]+?)(&|$)”))||[,null])[0]

    Funcoina correctamente excepto si el parámetro está vacio, por ejemplo si la url es así:
    …..&mpInputSearch=&otrParam=hola&…….

    Necesito decirle que después del “=” va cualquier parámetro menos “&”

    Gracias.

  9. como podria realizar una funcion en la cual no ingrese numeros y simbolos , solo letras , luego que me acepte todo .. pero al borrar o cambiar de cursor al inicio le ponemos un numero o simbolo que no lo aceepte .

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *