JavaScript para principiantes: aprendizaje de expresiones regulares. JavaScript expresivo: expresiones regulares

Expresiones regulares

expresión regular es un objeto que describe un patrón de carácter. La clase RegExp en JavaScript representa expresiones regulares, y los objetos de clase String y RegExp definen métodos que usan expresiones regulares para realizar coincidencias de patrones y operaciones de búsqueda y reemplazo de texto. La gramática de expresiones regulares de JavaScript contiene un subconjunto bastante completo de la sintaxis de expresiones regulares utilizada en Perl 5, por lo que si tiene experiencia con Perl, puede escribir patrones fácilmente en programas de JavaScript.

Las características de las expresiones regulares de Perl que no son compatibles con ECMAScript incluyen los indicadores s (modo de una sola línea) y x (sintaxis extendida); secuencias de escape \a, \e, \l, \u, \L, \U, \E, \Q, \A, \Z, \z y \G y otras construcciones extendidas que comienzan con (?.

Definición de expresiones regulares

En JavaScript, las expresiones regulares están representadas por objetos. ExpReg. Los objetos RegExp se pueden crear usando el constructor RegExp(), pero más a menudo se crean usando una sintaxis literal especial. Así como los literales de cadena se especifican como caracteres entre comillas, los literales de expresión regular se especifican como caracteres rodeados por un par de barras diagonales (/). Entonces tu código JavaScript podría contener líneas como esta:

Patrón var = /s$/;

Esta línea crea un nuevo objeto RegExp y lo asigna a la variable de patrón. Este objeto RegExp busca cualquier cadena que termine con el carácter "s". La misma expresión regular se puede definir usando el constructor RegExp():

Patrón var = nueva RegExp("s$");

Una especificación de patrón de expresión regular consta de una secuencia de caracteres. La mayoría de los caracteres, incluidos todos los caracteres alfanuméricos, describen literalmente los caracteres que deben estar presentes. Es decir, la expresión regular /java/ coincide con todas las líneas que contienen la subcadena “java”.

Otros caracteres en expresiones regulares no están destinados a usarse para encontrar sus equivalentes exactos, sino que tienen significados especiales. Por ejemplo, la expresión regular /s$/ contiene dos caracteres. El primer carácter s indica una búsqueda de un carácter literal. En segundo lugar, $ es un metacarácter especial que marca el final de una línea. Entonces esta expresión regular coincide con cualquier cadena que termine con el carácter s.

Las siguientes secciones describen los diversos caracteres y metacaracteres utilizados en expresiones regulares en JavaScript.

Caracteres literales

Como se señaló anteriormente, todos los caracteres alfabéticos y números de las expresiones regulares coinciden entre sí. La sintaxis de expresiones regulares en JavaScript también admite la capacidad de especificar ciertos caracteres no alfabéticos mediante secuencias de escape que comienzan con un carácter de barra invertida (\). Por ejemplo, la secuencia \n coincide con el carácter de nueva línea. Estos símbolos se enumeran en la siguiente tabla:

Algunos signos de puntuación tienen significados especiales en expresiones regulares:

^ $ . * + ? = ! : | \ / () { } -

El significado de estos símbolos se explica en las siguientes secciones. Algunas de ellas tienen un significado especial sólo en determinados contextos de expresiones regulares, mientras que en otros contextos se interpretan literalmente. Sin embargo, en general, para incluir literalmente cualquiera de estos caracteres en una expresión regular, debe precederlo con una barra invertida. Otros caracteres, como las comillas y @, no tienen ningún significado especial y simplemente coinciden entre sí en expresiones regulares.

Si no puede recordar exactamente qué caracteres deben ir precedidos por \, puede colocar con seguridad una barra invertida delante de cualquiera de los caracteres. Sin embargo, tenga en cuenta que muchas letras y números adquieren significados especiales cuando se combinan con el carácter de barra diagonal, por lo que las letras y números que está buscando literalmente no deben ir precedidos por un carácter \. Para incluir el carácter de barra invertida en una expresión regular, obviamente debe precederlo con otro carácter de barra invertida. Por ejemplo, la siguiente expresión regular coincide con cualquier cadena que contenga un carácter de barra invertida: /\\/.

Clases de personajes

Los caracteres literales individuales se pueden combinar en clases de caracteres encerrándolos entre corchetes. Una clase de personaje coincide con cualquier carácter contenido en esa clase. Por lo tanto, la expresión regular // coincide con uno de los caracteres a, b o c.

También se pueden definir clases de caracteres negativos para que coincidan con cualquier carácter excepto los especificados entre paréntesis. La clase de carácter de negación se especifica mediante el carácter ^ como primer carácter después del paréntesis izquierdo. La expresión regular /[^abc]/ coincide con cualquier carácter que no sea a, b o c. En las clases de caracteres, se puede especificar una variedad de caracteres mediante un guión. Todos los caracteres latinos en minúscula se encuentran usando la expresión //, y cualquier letra o número del conjunto de caracteres latinos se puede encontrar usando la expresión //.

Ciertas clases de caracteres son particularmente comunes, por lo que la sintaxis de las expresiones regulares en JavaScript incluye caracteres especiales y secuencias de escape para representarlos. Por lo tanto, \s coincide con espacios, tabulaciones y cualquier carácter de espacio en blanco Unicode, y \S coincide con cualquier carácter de espacio en blanco que no sea Unicode.

La siguiente tabla proporciona una lista de estos caracteres especiales y la sintaxis de las clases de caracteres. (Tenga en cuenta que algunas de las secuencias de escape de clases de caracteres coinciden solo con caracteres ASCII y no están extendidas para funcionar con caracteres Unicode. Puede definir explícitamente sus propias clases de caracteres Unicode, por ejemplo, /[\u0400-\u04FF]/ coincide con cualquier carácter del alfabeto cirílico. .)

Clases de caracteres de expresión regular de JavaScript
Símbolo Correspondencia
[...] Cualquiera de los caracteres que se muestran entre paréntesis
[^...] Cualquiera de los caracteres que no figuran entre paréntesis
. Cualquier carácter que no sea una nueva línea u otro delimitador de línea Unicode
\w Cualquier carácter de texto ASCII. Equivalente
\W Cualquier carácter que no sea un carácter de texto ASCII. Equivalente a [^a-zA-Z0-9_]
\s Cualquier carácter de espacio en blanco del conjunto Unicode
\S Cualquier carácter que no sea un espacio en blanco del conjunto Unicode. Tenga en cuenta que los caracteres \w y \S no son lo mismo
\d Cualquier número ASCII. Equivalente
\D Cualquier carácter que no sea un número ASCII. Equivalente a [^0-9]
[\b] Literal de carácter de retroceso

Tenga en cuenta que las secuencias de escape de caracteres especiales de clase se pueden encerrar entre corchetes. \s coincide con cualquier carácter de espacio en blanco y \d coincide con cualquier dígito, por lo tanto, /[\s\d]/ coincide con cualquier carácter de espacio en blanco o dígito.

Repetición

Dado el conocimiento de la sintaxis de expresiones regulares adquirido hasta ahora, podemos describir un número de dos dígitos como /\d\d/ o un número de cuatro dígitos como /\d\d\d\d/, pero no podemos, por ejemplo , describe un número que consta de cualquier número de dígitos o una cadena de tres letras seguidas de un dígito opcional. Estos patrones más complejos utilizan la sintaxis de expresión regular, que especifica cuántas veces se puede repetir un elemento de expresión regular determinado.

Los símbolos repetidos siempre siguen el patrón al que se aplican. Algunos tipos de repeticiones se utilizan con bastante frecuencia y hay símbolos especiales disponibles para indicar estos casos. Por ejemplo, + coincide con una o más instancias del patrón anterior. La siguiente tabla proporciona un resumen de la sintaxis de repetición:

Las siguientes líneas muestran varios ejemplos:

Patrón var = /\d(2,4)/; // Coincide con un número que contiene de dos a cuatro dígitos patrón = /\w(3)\d?/; // Coincide exactamente con tres caracteres de palabras y un patrón de dígitos opcional = /\s+java\s+/; // Coincide con la palabra "java" con uno o más espacios // antes y después de ella patrón = /[^(]*/; // Coincide con cero o más caracteres distintos del paréntesis de apertura

Tenga cuidado al utilizar caracteres repetidos * y ?. Pueden coincidir con la ausencia de un patrón especificado ante ellos y, por tanto, con la ausencia de caracteres. Por ejemplo, la expresión regular /a*/ coincide con la cadena "bbbb" porque no contiene el carácter a.

Los caracteres de repetición enumerados en la tabla representan el número máximo posible de repeticiones que permitirán que coincidan las partes posteriores de la expresión regular. Decimos que esto es una repetición codiciosa. También es posible implementar la repetición realizada de manera no codiciosa. Basta indicar un signo de interrogación después del símbolo (o símbolos) de repetición: ??, +?, *? o incluso (1,5)?.

Por ejemplo, la expresión regular /a+/ coincide con una o más instancias de la letra a. Aplicado a la cadena "aaa", coincide con las tres letras. Por otro lado, la expresión /a+?/ coincide con una o más instancias de la letra a y selecciona el menor número posible de caracteres. Aplicado a la misma cuerda, este patrón coincide solo con la primera letra a.

La repetición “sin avaricia” no siempre da el resultado esperado. Considere el patrón /a+b/, que coincide con una o más a seguidas de una b. Cuando se aplica a la cadena "aaab", corresponde a la cadena completa.

Ahora revisemos la versión "no codiciosa" de /a+?b/. Se podría pensar que coincidiría con una b precedida sólo por una a. Si se aplica a la misma cadena, se esperaría que "aaab" coincida con el carácter único a y el último carácter b. Sin embargo, este patrón en realidad coincide con toda la cadena, al igual que la versión codiciosa. El hecho es que una búsqueda de patrón de expresión regular se realiza encontrando la primera posición en la cadena, a partir de la cual es posible una coincidencia. Dado que es posible una coincidencia a partir del primer carácter de la cadena, ni siquiera se consideran coincidencias más cortas a partir de los caracteres siguientes.

Alternativas, Agrupaciones y Enlaces

La gramática de las expresiones regulares incluye caracteres especiales para definir alternativas, agrupar subexpresiones y referencias a subexpresiones anteriores. Símbolo de tubería | Sirve para separar alternativas. Por ejemplo, /ab|cd|ef/ coincide con la cadena "ab", o la cadena "cd", o la cadena "ef", y el patrón /\d(3)|(4)/ coincide con tres dígitos o cuatro letras minúsculas.

Tenga en cuenta que las alternativas se procesan de izquierda a derecha hasta que se encuentra una coincidencia. Si se encuentra una coincidencia con la alternativa izquierda, se ignora la derecha, incluso si se puede lograr una coincidencia "mejor". Entonces, cuando el patrón /a|ab/ se aplica a la cadena "ab", solo coincidirá con el primer carácter.

Los paréntesis tienen múltiples significados en las expresiones regulares. Uno de ellos es agrupar elementos individuales en una subexpresión, de modo que los elementos cuando utilicen los caracteres especiales |, *, +, ? y otros se consideran como un todo. Por ejemplo, el patrón /java(script)?/ coincide con la palabra "java" seguida de la palabra opcional "script", y /(ab|cd)+|ef)/ coincide con la cadena "ef" o una o más repeticiones de una de las cadenas "ab" o "cd".

Otro uso de los paréntesis en las expresiones regulares es definir subpatrones dentro de un patrón. Cuando se encuentra una coincidencia de expresión regular en la cadena de destino, se puede extraer la parte de la cadena de destino que coincide con cualquier subpatrón específico entre paréntesis.

Suponga que desea buscar una o más letras minúsculas seguidas de uno o más números. Para hacer esto, puede usar la plantilla /+\d+/. Pero supongamos también que sólo queremos los números al final de cada partido. Si ponemos esta parte del patrón entre paréntesis (/+(\d+)/), podemos extraer números de cualquier coincidencia que encontremos. A continuación se describirá cómo se hace esto.

Un uso relacionado de las subexpresiones entre paréntesis es hacer referencia a subexpresiones de una parte anterior de la misma expresión regular. Esto se logra especificando uno o más dígitos después del carácter \. Los números se refieren a la posición de la subexpresión entre paréntesis dentro de la expresión regular. Por ejemplo, \1 se refiere a la primera subexpresión y \3 se refiere a la tercera. Tenga en cuenta que las subexpresiones se pueden anidar entre sí, por lo que se utiliza la posición del paréntesis izquierdo al contar. Por ejemplo, en la siguiente expresión regular, una referencia de subexpresión anidada (cript) tendría un aspecto similar a \2:

/(ava(cript)?)\sis\s(diversión\w*)/

Una referencia a una subexpresión anterior no apunta al patrón de esa subexpresión, sino al texto encontrado que coincide con ese patrón. Por lo tanto, las referencias se pueden utilizar para imponer una restricción que seleccione partes de una cadena que contengan exactamente los mismos caracteres. Por ejemplo, la siguiente expresión regular coincide con cero o más caracteres entre comillas simples o dobles. Sin embargo, no requiere que las comillas de apertura y cierre coincidan (es decir, que ambas comillas sean simples o dobles):

/[""][^""]*[""]/

Podemos exigir que las comillas coincidan usando una referencia como esta:

Aquí \1 coincide con la primera subexpresión. En este ejemplo, el vínculo impone una restricción que requiere que las comillas de cierre coincidan con las comillas de apertura. Esta expresión regular no permite comillas simples dentro de comillas dobles y viceversa.

También es posible agrupar elementos en una expresión regular sin crear una referencia numerada a esos elementos. En lugar de simplemente agrupar elementos entre ( y ), comience el grupo con símbolos (?: y finalícelo con un símbolo). Considere, por ejemplo, el siguiente patrón:

/(ava(?:cript)?)\sis\s(diversión\w*)/

Aquí la subexpresión (?:cript) solo es necesaria para agrupar, de modo que se pueda aplicar el carácter de repetición al grupo. Estos paréntesis modificados no crean un vínculo, por lo que en esta expresión regular, \2 se refiere al texto que coincide con el patrón (divertido\w*).

La siguiente tabla enumera los operadores de selección, agrupación y referencia en expresiones regulares:

Selección, agrupación y enlace de símbolos de expresiones regulares de JavaScript
Símbolo Significado
| Alternativa. Coincide con la subexpresión de la izquierda o la subexpresión de la derecha.
(...) Agrupamiento. Agrupa elementos en una sola unidad que se puede utilizar con los caracteres *, +, ?, | etc. También recuerda los caracteres que coinciden con este grupo para usarlos en referencias posteriores.
(?:...) Sólo agrupación. Agrupa elementos en una sola unidad, pero no recuerda los personajes que corresponden a ese grupo.
\número Coincide con los mismos caracteres que se encontraron al hacer coincidir el número de grupo. Los grupos son subexpresiones dentro de paréntesis (posiblemente anidadas). Los números de grupo se asignan contando los paréntesis izquierdos de izquierda a derecha. Los grupos formados con los símbolos (?:) no están numerados.

Especificación de una posición de partido

Como se describió anteriormente, muchos elementos de una expresión regular coinciden con un solo carácter en una cadena. Por ejemplo, \s coincide con un único carácter de espacio en blanco. Otros elementos de expresiones regulares coinciden con las posiciones entre caracteres en lugar de con los caracteres mismos. Por ejemplo, \b coincide con el límite de una palabra: el límite entre \w (un carácter de texto ASCII) y \W (un carácter que no es de texto), o el límite entre un carácter de texto ASCII y el principio o el final de una línea.

Elementos como \b no especifican ningún carácter que deba estar presente en la cadena coincidente, pero sí especifican posiciones válidas para la coincidencia. Estos elementos a veces se denominan elementos ancla de expresión regular porque anclan el patrón a una posición específica en la cadena. Los elementos de anclaje más utilizados son ^ y $, que vinculan patrones al principio y al final de una línea, respectivamente.

Por ejemplo, la palabra "JavaScript" en su propia línea se puede encontrar usando la expresión regular /^JavaScript$/. Para encontrar una sola palabra "Java" (en lugar de un prefijo como "JavaScript"), puede intentar usar el patrón /\sJava\s/, que requiere un espacio antes y después de la palabra.

Pero tal solución plantea dos problemas. En primer lugar, sólo encontrará la palabra "Java" si está rodeada de espacios en ambos lados y no podrá encontrarla al principio ni al final de la línea. En segundo lugar, cuando este patrón coincide, la cadena que devuelve contendrá espacios iniciales y finales, que no es exactamente lo que queremos. Entonces, en lugar de usar un patrón que coincida con los caracteres de espacio en blanco \s, usaremos un patrón (o ancla) que coincida con los límites de las palabras \b. El resultado será la siguiente expresión: /\bJava\b/.

El elemento ancla \B coincide con una posición que no es un límite de palabra. Es decir, el patrón /\Bcript/ coincidirá con las palabras “JavaScript” y “postscript” y no coincidirá con las palabras “script” o “Scripting”.

Las expresiones regulares arbitrarias también pueden servir como condiciones ancla. Si coloca una expresión entre los caracteres (?= y), se convierte en una prueba de coincidencia directa con los caracteres posteriores, lo que requiere que esos caracteres coincidan con el patrón especificado pero no se incluyan en la cadena de coincidencia.

Por ejemplo, para hacer coincidir el nombre de un lenguaje de programación común seguido de dos puntos, puede utilizar la expresión /ava(cript)?(?=\:)/. Este patrón coincide con la palabra "JavaScript" en la cadena "JavaScript: The Definitive Guide", pero no coincidirá con la palabra "Java" en la cadena "Java in a Nutshell" porque no va seguida de dos puntos.

Si ingresa la condición (?!), esto será una verificación directa negativa para los caracteres posteriores, lo que requerirá que los siguientes caracteres no coincidan con el patrón especificado. Por ejemplo, el patrón /Java(?!Script)(\w*. )/ coincide con la subcadena "Java", seguida de una letra mayúscula y cualquier número de caracteres de texto ASCII, siempre que la subcadena "Java" no esté seguida por la subcadena "Script". Coincidirá con la cadena "JavaBeans", pero lo hará. no coincidirá con la cadena "Javanese", coincidirá con la cadena "JavaScrip", pero no coincidirá con las cadenas "JavaScript" o "JavaScripter".

La siguiente tabla proporciona una lista de caracteres ancla de expresiones regulares:

Caracteres de anclaje de expresión regular
Símbolo Significado
^ Coincide con el comienzo de una expresión de cadena o el comienzo de una línea en una búsqueda multilínea.
$ Coincide con el final de una expresión de cadena o el final de una línea en una búsqueda multilínea.
\b Coincide con un límite de palabra, es decir coincide con la posición entre el carácter \w y el carácter \W, o entre el carácter \w y el principio o el final de una línea. (Tenga en cuenta, sin embargo, que [\b] coincide con el carácter de retroceso).
\B Coincide con una posición que no es un límite de palabra.
(?=pag) Comprobación positiva de anticipación para caracteres posteriores. Requiere que los caracteres posteriores coincidan con el patrón p, pero no incluye esos caracteres en la cadena coincidente.
(?!pag) Comprobación directa negativa para caracteres posteriores. Requiere que los siguientes caracteres no coincidan con el patrón p.

Banderas

Y un último elemento de la gramática de las expresiones regulares. Los indicadores de expresión regular especifican reglas de coincidencia de patrones de alto nivel. A diferencia del resto de la gramática de expresiones regulares, las banderas no se especifican entre los caracteres de barra diagonal, sino después del segundo. JavaScript admite tres banderas.

Bandera yo especifica que la coincidencia de patrones no debe distinguir entre mayúsculas y minúsculas, y bandera g- que la búsqueda debe ser global, es decir se deben encontrar todas las coincidencias en la cadena. Bandera m realiza una búsqueda de patrón en modo multilínea. Si la expresión de cadena que se busca contiene nuevas líneas, entonces en este modo los caracteres de anclaje ^ y $, además de coincidir con el principio y el final de toda la expresión de cadena, también coinciden con el principio y el final de cada línea de texto. Por ejemplo, el patrón /java$/im coincide tanto con “java” como con “Java\nis fun”.

Estas banderas se pueden combinar en cualquier combinación. Por ejemplo, para buscar la primera aparición de la palabra "java" (o "Java", "JAVA", etc.) sin distinguir entre mayúsculas y minúsculas, puede utilizar la expresión regular /\bjava\b/ que no distingue entre mayúsculas y minúsculas. i. Y para encontrar todas las apariciones de esta palabra en una cadena, puede agregar la bandera g: /\bjava\b/gi.

Métodos de la clase String para buscar por patrón

Hasta este punto, hemos discutido la gramática de las expresiones regulares generadas, pero no hemos visto cómo esas expresiones regulares pueden usarse realmente en scripts JavaScript. En esta sección, analizaremos los métodos del objeto String que utilizan expresiones regulares para la coincidencia de patrones y la búsqueda con reemplazo. Y luego continuaremos nuestra conversación sobre la coincidencia de patrones con expresiones regulares observando el objeto RegExp y sus métodos y propiedades.

Strings admite cuatro métodos que utilizan expresiones regulares. El más simple de ellos es el método. buscar(). Toma una expresión regular como argumento y devuelve la posición del primer carácter de la subcadena coincidente o -1 si no se encuentra ninguna coincidencia. Por ejemplo, la siguiente llamada devolverá 4:

Resultado var = "JavaScript".search(/script/i); // 4

Si el argumento del método search() no es una expresión regular, primero se convierte pasándolo al constructor RegExp. El método search() no admite la búsqueda global e ignora la bandera g en su argumento.

Método reemplazar() realiza una operación de búsqueda y reemplazo. Toma una expresión regular como primer argumento y una cadena de reemplazo como segundo. El método busca en la línea en la que se llama una coincidencia con el patrón especificado.

Si la expresión regular contiene la bandera g, el método reemplazar() reemplaza todas las coincidencias encontradas con la cadena de reemplazo. De lo contrario, reemplaza sólo la primera coincidencia encontrada. Si el primer argumento del método replace() es una cadena en lugar de una expresión regular, entonces el método realiza una búsqueda literal de la cadena en lugar de convertirla en una expresión regular usando el constructor RegExp() como lo hace el método search().

Como ejemplo, podemos usar el método reemplazar() para poner en mayúscula la palabra "JavaScript" de manera consistente en toda una línea de texto:

// Independientemente del caso de los caracteres, los reemplazamos con una palabra en el caso requerido var result = "javascript".replace(/JavaScript/ig, "JavaScript");

El método replace() es más poderoso de lo que sugiere este ejemplo. Déjame recordarte que las subexpresiones entre paréntesis dentro de una expresión regular están numeradas de izquierda a derecha, y que la expresión regular recuerda el texto correspondiente a cada una de las subexpresiones. Si la cadena de reemplazo contiene un signo $ seguido de un número, el método reemplazar() reemplaza esos dos caracteres con el texto que coincide con la subexpresión especificada. Esta es una característica muy útil. Podemos usarlo, por ejemplo, para reemplazar comillas rectas en una cadena por comillas tipográficas, que son simuladas por caracteres ASCII:

// Una comilla es una comilla seguida de cualquier número de caracteres // distintos de las comillas (que recordamos), seguidas de otra comilla // var quote = /"([^"]*)"/g; // Reemplazar el comillas rectas con tipográficas y dejar "$1" sin cambios // el contenido de la cita almacenado en $1 var text = ""JavaScript" es un lenguaje de programación interpretado."; var result = text.replace(quote, ""$1"" ) ; // "JavaScript" es un lenguaje de programación interpretado.

Una cosa importante a tener en cuenta es que el segundo argumento para reemplazar() puede ser una función que calcule dinámicamente la cadena de reemplazo.

Método fósforo() es el más general de los métodos de la clase String que utiliza expresiones regulares. Toma una expresión regular como único argumento (o convierte su argumento en una expresión regular pasándola al constructor RegExp()) y devuelve una matriz que contiene los resultados de la búsqueda. Si la bandera g está configurada en la expresión regular, el método devuelve una matriz de todas las coincidencias presentes en la cadena. Por ejemplo:

// devolverá ["1", "2", "3"] var resultado = "1 más 2 es igual a 3".match(/\d+/g);

Si la expresión regular no contiene el indicador g, el método match() no realiza una búsqueda global; solo busca el primer partido. Sin embargo, match() devuelve una matriz incluso cuando el método no realiza una búsqueda global. En este caso, el primer elemento de la matriz es la subcadena encontrada y todos los elementos restantes son subexpresiones de la expresión regular. Por lo tanto, si match() devuelve una matriz arr, entonces arr contendrá la cadena completa encontrada, arr la subcadena correspondiente a la primera subexpresión, etc. Haciendo un paralelo con el método replace(), podemos decir que el contenido de $n se ingresa en arr[n].

Por ejemplo, observe el siguiente código que analiza una URL:

Var URL = /(\w+):\/\/([\w.]+)\/(\S*)/; var text = "Visite nuestro sitio web http://www..php"; resultado var = text.match(url); if (resultado! = nulo) ( var fullurl = resultado; // Contiene "http://www..php" var protocolo = resultado; // Contiene "http" var host = resultado; // Contiene "www..php " )

Cabe señalar que para una expresión regular que no tiene establecido el indicador de búsqueda global g, el método match() devuelve el mismo valor que el método exec() de la expresión regular: la matriz devuelta tiene las propiedades index y input, como se describe en la discusión del ejecutivo () a continuación.

El último de los métodos del objeto String que utiliza expresiones regulares es dividir(). Este método divide la cadena en la que se llama en una matriz de subcadenas, utilizando el argumento como delimitador. Por ejemplo:

"123,456,789".split(","); // Devuelve ["123","456","789"]

El método split() también puede tomar una expresión regular como argumento. Esto hace que el método sea más poderoso. Por ejemplo, puede especificar un separador que permita una cantidad arbitraria de caracteres de espacio en blanco en ambos lados:

"1, 2, 3, 4, 5".split(/\s*,\s*/); // Devuelve ["1","2","3","4","5"]

Objeto RegExp

Como se mencionó, las expresiones regulares se representan como objetos RegExp. Además del constructor RegExp(), los objetos RegExp admiten tres métodos y varias propiedades.

El constructor RegExp() toma uno o dos argumentos de cadena y crea un nuevo objeto RegExp. El primer argumento del constructor es una cadena que contiene el cuerpo de la expresión regular, es decir texto que debe aparecer entre caracteres de barra diagonal en un literal de expresión regular. Tenga en cuenta que los literales de cadena y las expresiones regulares usan el carácter \ para representar secuencias de escape, por lo que al pasar la expresión regular como un literal de cadena al constructor RegExp(), debe reemplazar cada carácter \ con un par de caracteres \\.

Es posible que falte el segundo argumento de RegExp(). Si se especifica, define los indicadores de expresión regular. Debe ser uno de los caracteres g, i, m o una combinación de estos caracteres. Por ejemplo:

// Encuentra todos los números de cinco dígitos en una cadena. Nota // el uso de símbolos en este ejemplo \\ var zipcode = new RegExp("\\d(5)", "g");

El constructor RegExp() es útil cuando la expresión regular se genera dinámicamente y, por lo tanto, no se puede representar mediante la sintaxis literal de expresión regular. Por ejemplo, para encontrar una cadena ingresada por el usuario, necesita crear una expresión regular en tiempo de ejecución usando RegExp().

Propiedades de expresión regular

Cada objeto RegExp tiene cinco propiedades. Propiedad fuente- una cadena de solo lectura que contiene el texto de la expresión regular. Propiedad global es un valor booleano de solo lectura que especifica si el indicador g está presente en la expresión regular. Propiedad ignorar caso es un valor booleano de sólo lectura que determina si el indicador i está presente en la expresión regular. Propiedad multilínea es un valor booleano de solo lectura que determina si el indicador m está presente en la expresión regular. Y la última propiedad último índice es un número entero que se puede leer y escribir. Para patrones con la bandera g, esta propiedad contiene el número de posición en la línea en la que debe comenzar la siguiente búsqueda. Como se describe a continuación, lo utilizan los métodos exec() y test().

Métodos de expresión regular

Los objetos RegExp definen dos métodos que realizan coincidencia de patrones; se comportan de manera similar a los métodos de la clase String descritos anteriormente. El método principal de la clase RegExp utilizada para la coincidencia de patrones es ejecutivo(). Es similar al método Match() de la clase String mencionado anteriormente, excepto que es un método de clase RegExp que toma una cadena como argumento, en lugar de un método de clase String que toma un argumento RegExp.

El método exec() ejecuta la expresión regular para la cadena especificada, es decir busca una coincidencia en una cadena. Si no se encuentra ninguna coincidencia, el método devuelve nulo. Sin embargo, si se encuentra una coincidencia, devuelve la misma matriz que la matriz devuelta por el método match() para buscar sin la bandera g. El elemento cero de la matriz contiene la cadena que coincide con la expresión regular y todos los elementos posteriores contienen subcadenas que coinciden con todas las subexpresiones. Además, la propiedad índice contiene el número de posición del carácter con el que comienza el fragmento correspondiente y la propiedad aporte se refiere a la línea que se buscó.

A diferencia de match(), el método exec() devuelve una matriz cuya estructura no depende de la presencia de la bandera g en la expresión regular. Permítanme recordarles que al pasar una expresión regular global, el método match() devuelve una serie de coincidencias encontradas. Y exec() siempre devuelve una coincidencia, pero proporciona información completa al respecto. Cuando se llama a exec() en una expresión regular que contiene el indicador g, el método establece la propiedad lastIndex del objeto de expresión regular en el número de posición del carácter inmediatamente después de la subcadena encontrada.

Cuando se llama a exec() por segunda vez en la misma expresión regular, comienza la búsqueda en el carácter cuya posición se especifica en la propiedad lastIndex. Si exec() no encuentra una coincidencia, la propiedad lastIndex se establece en 0. (También puede establecer lastIndex en cero en cualquier momento, lo que debe hacerse en todos los casos en los que la búsqueda finaliza antes de que se muestre la última coincidencia en una sola fila). encontrado y la búsqueda comienza en otra línea con el mismo objeto RegExp.) Este comportamiento especial permite llamar a exec() repetidamente para iterar sobre todas las coincidencias de la expresión regular en la línea. Por ejemplo:

Patrón var = /Java/g; var text = "¡JavaScript es más divertido que Java!"; resultado de la variable; while((resultado = patrón.exec(texto)) != nulo) ( console.log("Encontrado "" + resultado + """ + " en la posición " + resultado.index + "; la próxima búsqueda comenzará en " + patrón .lastIndex);

Otro método del objeto RegExp es prueba(), que es mucho más simple que el método exec(). Toma una cadena y devuelve verdadero si la cadena coincide con la expresión regular:

Patrón var = /java/i; patrón.prueba("JavaScript"); // Devuelve verdadero

Llamar a test() es equivalente a llamar a exec(), que devuelve verdadero si exec() devuelve algo distinto de nulo. Por esta razón, el método test() se comporta de la misma manera que el método exec() cuando se le llama en una expresión regular global: comienza a buscar la cadena especificada en la posición especificada por la propiedad lastIndex, y si encuentra una coincidencia , establece la propiedad lastIndex en el número de posición del carácter directamente al lado de la coincidencia encontrada. Por lo tanto, utilizando el método test(), puede crear un bucle transversal de línea de la misma manera que utilizando el método exec().

En JavaScript, las expresiones regulares están representadas por objetos RegExp. Los objetos RegExp se pueden crear usando el constructor RegExp(), pero más a menudo se crean usando una sintaxis literal especial. Así como los literales de cadena se especifican como caracteres entre comillas, los literales de expresiones regulares se especifican como caracteres entre un par de barras diagonales / .

/pattern/flags new RegExp("patrón"[, opciones de búsqueda])

patrón- una expresión regular para buscar (más sobre el reemplazo más adelante) y banderas - una cadena de cualquier combinación de caracteres g (búsqueda global), i (las mayúsculas y minúsculas no son importantes) y m (búsqueda de varias líneas). El primer método se utiliza a menudo, el segundo, a veces. Por ejemplo, dos de estas llamadas son equivalentes.

Opciones de búsqueda

Al crear una expresión regular, podemos especificar opciones de búsqueda adicionales.

Caracteres en expresiones regulares de JavaScript

SímboloCorrespondencia
Caracteres alfanuméricoscorresponden a ellos mismos
\0 Carácter nulo (\u0000)
\ tPestaña (\u0009)
\norteAvance de línea (\u000A)
\vPestaña vertical (\u000B)
\FTraducción de página (\u000C)
\rRetorno de carro (\u000D)
\xnnUn carácter del conjunto latino, especificado por el número hexadecimal nn; por ejemplo, \x0A es lo mismo que \n
\uxxxxCarácter Unicode especificado por el número hexadecimal xxxx; por ejemplo, \u0009 es lo mismo que \t
\cXEl carácter de control "X", por ejemplo, la secuencia \cJ es equivalente al carácter de nueva línea \n
\ Para personajes normales, los hace especiales. Por ejemplo, la expresión /s/ simplemente busca el carácter "s". Y si pones \ antes de s, entonces /\s/ ya denota un carácter de espacio y viceversa, si el carácter es especial, por ejemplo *, entonces \ lo convertirá en un carácter de “asterisco” normal. Por ejemplo, /a*/ busca 0 o más caracteres "a" consecutivos. Para encontrar a con un asterisco "a*", coloque \ delante del especial. símbolo: /a\*/ .
^ Indica el comienzo de los datos de entrada. Si se establece el indicador de búsqueda multilínea ("m"), también se activará al comienzo de una nueva línea. Por ejemplo, /^A/ no encontrará la "A" en "una A", pero encontrará la primera. "A" en "Una A".
$ Indica el final de los datos de entrada. Si el indicador de búsqueda multilínea está configurado, también funcionará al final de la línea. Por ejemplo, /t$/ no encontrará "t" en "eater", pero sí en "eat".
* Indica repetición 0 o más veces. Por ejemplo, /bo*/ encontrará "boooo" en "Un fantasma abucheó" y "b" en "Un pájaro trinó", pero no encontrará nada en "Una cabra gruñó".
+ Indica repetición 1 o más veces. Equivalente a (1,). Por ejemplo, /a+/ coincidirá con la "a" de "candy" y con todas las "a" de "caaaaaaandy".
? Indica que el elemento puede estar presente o no. Por ejemplo, /e?le?/ coincidirá con "el" en "angel" y "le" en "angle". Si se usa inmediatamente después de uno de los cuantificadores * , + , ? , o () , luego especifica una búsqueda "no codiciosa" (que se repite el mínimo número de veces posible, hasta el siguiente elemento de patrón más cercano), a diferencia del modo "codicioso" predeterminado, en el que el número de repeticiones es máximo, incluso si el siguiente elemento del patrón también coincide. utilizado en la vista previa, que se describe en la tabla bajo (?=) , (?!) y (?:) .
. (Punto decimal) representa cualquier carácter que no sea una nueva línea: \n \r \u2028 o \u2029. (puede utilizar [\s\S] para buscar cualquier carácter, incluidas las nuevas líneas). Por ejemplo, /.n/ coincidirá con "an" y "on" en "no, hay una manzana en el árbol", pero no con "no".
(incógnita)Encuentra x y recuerda. Esto se llama "paréntesis de memoria". Por ejemplo, /(foo)/ encontrará y recordará "foo" en la "barra foo". La subcadena encontrada se almacena en la matriz de resultados de la búsqueda o en las propiedades predefinidas del objeto RegExp: $1, ..., $9. Además, los paréntesis combinan lo que contienen en un único elemento de patrón. Por ejemplo, (abc)* - repite abc 0 o más veces.
(?:incógnita)Encuentra x, pero no recuerda lo que encuentra. Esto se llama "paréntesis de memoria". La subcadena encontrada no se almacena en la matriz de resultados y las propiedades RegExp. Como todos los corchetes, combinan lo que contienen en un único subpatrón.
x(?=y)Encuentra x sólo si x va seguido de y. Por ejemplo, /Jack(?=Espadín)/ sólo coincidirá con "Jack" si va seguido de "Espadín". /Jack(?=Sprat|Frost)/ sólo coincidirá con "Jack" si va seguido de "Sprat" o "Frost". Sin embargo, ni "Sprat" ni "Frost" aparecerán en el resultado de la búsqueda.
x(?!y)Encuentra x sólo si x no es seguido por y. Por ejemplo, /\d+(?!\.)/ solo coincidirá con un número si no va seguido de un punto decimal. /\d+(?!\.)/.exec("3.141") encontrará 141, pero no 3.141.
x|yEncuentra x o y. Por ejemplo, /verde|rojo/ coincidirá con "verde" en "manzana verde" y "rojo" en "manzana roja".
(norte)Donde n es un número entero positivo. Encuentra exactamente n repeticiones del elemento anterior. Por ejemplo, /a(2)/ no encontrará la "a" en "candy", pero encontrará ambas a en "caandy" y las dos primeras a en "caaandy".
(norte,)Donde n es un número entero positivo. Encuentra no más repeticiones de un elemento. Por ejemplo, /a(2,) no encontrará "a" en "candy", pero encontrará todas las "a" en "caandy" y en "caaaaaaandy".
(Nuevo Méjico)Donde n y m son números enteros positivos. Encuentre de n a m repeticiones del elemento.
Conjunto de caracteres. Encuentra cualquiera de los caracteres enumerados. Puede indicar el espaciado utilizando un guión. Por ejemplo, lo mismo que . Coincide con "b" en "brisket" y "a" y "c" en "ache".
[^xyz]Cualquier carácter distinto de los especificados en el conjunto. También puede especificar un intervalo. Por ejemplo, [^abc] es lo mismo que [^a-c] . Encuentra "r" en "pechuga" y "h" en "chuleta".
[\b]Encuentra el carácter de retroceso. (No debe confundirse con \b .)
\bEncuentra el límite de una palabra (latina), como un espacio. (No confundir con [\b]). Por ejemplo, /\bn\w/ coincidirá con "no" en "mediodía"; /\wy\b/ coincidirá con "ly" en "posiblemente ayer".
\BNo indica un límite de palabra. Por ejemplo, /\w\Bn/ coincidirá con "on" en "mediodía" y /y\B\w/ coincidirá con "ye" en "posiblemente ayer".
\cXDonde X es una letra de la A a la Z. Indica un carácter de control en una cadena. Por ejemplo, /\cM/ representa el carácter Ctrl-M.
\dencuentra un número de cualquier alfabeto (el nuestro es Unicode). Úselo para buscar solo números regulares. Por ejemplo, /\d/ o // coincidirá con el "2" en "B2 es el número de suite".
\DEncuentra un carácter no numérico (todos los alfabetos). [^0-9] es el equivalente a los números normales. Por ejemplo, /\D/ o /[^0-9]/ coincidirá con la "B" en "B2 es el número de suite".
\sCoincide con cualquier carácter de espacio en blanco, incluidos espacios, tabulaciones, nuevas líneas y otros caracteres de espacios en blanco Unicode. Por ejemplo, /\s\w*/ coincidirá con "bar" en "foo bar".
\SEncuentra cualquier carácter excepto espacios en blanco. Por ejemplo, /\S\w*/ coincidirá con "foo" en "foo bar".
\vCarácter de tabulación vertical.
\wEncuentra cualquier carácter de palabra (alfabeto latino), incluidas letras, números y guiones bajos. Equivalente. Por ejemplo, /\w/ coincidirá con "a" en "apple", "5" en "$5.28" y "3" en "3D".
\WEncuentra cualquier carácter verbal no (latino). Equivalente a [^A-Za-z0-9_] . Por ejemplo, /\W/ y /[^$A-Za-z0-9_]/ coincidirán igualmente con "%" en "50%".

Trabajar con expresiones regulares en Javascript

Trabajar con expresiones regulares en Javascript se implementa utilizando métodos de la clase String

exec(regexp): busca todas las coincidencias (entradas en el patrón regular) en una cadena. Devuelve una matriz (si hay una coincidencia) y actualiza la propiedad regexp, o nula si no se encuentra nada. Con el modificador g, cada vez que se llama a esta función, devolverá la siguiente coincidencia después de la anterior encontrada, esto se implementa manteniendo un índice de desplazamiento de la última búsqueda.

match(regexp): busca parte de una cadena usando un patrón. Si se especifica el modificador g, entonces match() devuelve una matriz de todas las coincidencias o nula (en lugar de una matriz vacía). Sin el modificador g, esta función funciona como exec();

test(regexp): la función comprueba que una cadena coincida con un patrón. Devuelve verdadero si hay una coincidencia y falso si no hay coincidencia.

split(regexp): divide la cadena a la que se llama en una matriz de subcadenas, utilizando el argumento como delimitador.

reemplazar(regexp, mix): el método devuelve una cadena modificada de acuerdo con la plantilla (expresión regular). El primer parámetro de la expresión regular también puede ser una cadena en lugar de una expresión regular. Sin el modificador g, el método de la línea reemplaza sólo la primera aparición; con el modificador g - se produce un reemplazo global, es decir Se cambian todas las apariciones de una línea determinada.

mix: plantilla de reemplazo, puede aceptar los valores de una cadena, plantilla de reemplazo, función (nombre de función).

Caracteres especiales en la cadena de reemplazo

Reemplazo mediante función

Si especifica una función como segundo parámetro, se ejecuta en cada coincidencia. Una función puede generar y devolver dinámicamente una cadena de sustitución. El primer parámetro de la función es la subcadena encontrada. Si el primer argumento a reemplazar es un objeto RegExp, los siguientes n parámetros contienen coincidencias entre paréntesis anidados. Los dos últimos parámetros son la posición en la línea donde ocurrió la coincidencia y la línea misma.

La clase RegExp en JavaScript es una expresión regular, un objeto que describe un patrón de caracteres. Los objetos RegExp normalmente se crean usando la sintaxis literal especial que se presenta a continuación, pero también se pueden crear usando el constructor RegExp().

Sintaxis// usando una sintaxis literal especial var expresión regular = /patrón /flags;// usando el constructor

var regex = new RegExp("patrón", "banderas "); var regex = new RegExp(/pattern /, "banderas ");

Valores de los parámetros:

Banderas de expresión regularBandera
Descripcióngramo Le permite buscar todas las coincidencias en lugar de detenerse después de la primera coincidencia ().
bandera de partido globali Permite coincidencias que no distinguen entre mayúsculas y minúsculas ().
ignorar la bandera del casoLa coincidencia se realiza en varias filas. Los caracteres iniciales y finales (^ y $) se procesan en varias líneas, lo que significa que la coincidencia se produce al principio o al final de cada línea (delimitadores \n o \r), y no solo al principio o al final de toda la línea ( bandera multilínea).
tuEl patrón se interpretará como una secuencia de puntos de código Unicode ( bandera unicode).
yLa coincidencia se produce en el índice señalado por la propiedad lastIndex de esta expresión regular, mientras que la coincidencia no se realiza en un índice anterior o posterior ( bandera pegajosa).

Conjuntos de caracteres

Metacaracteres

SímboloBandera
. Le permite buscar un solo carácter que no sea un carácter de nueva línea o de fin de línea (\n, \r, \u2028 o \u2029).
\dLe permite encontrar un símbolo numérico en el alfabeto latino básico. Equivale a utilizar el juego de caracteres.
\DLe permite encontrar cualquier carácter que no sea un número en el alfabeto latino básico. Equivalente al juego de caracteres [^0-9].
\sLe permite encontrar un único carácter de espacio en blanco. Los espacios en blanco se refieren a espacios, tabulaciones, avances de página, avances de línea y otros caracteres de espacios en blanco Unicode. Equivalente al conjunto de caracteres [\f\n\r\t\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004​\u2005\u2006​\u2007\u2008​\u2009\ u200a​ \u2028\u2029​\u202f\u205f​\u3000].
\SLe permite encontrar un solo carácter que no sea un espacio en blanco. Los espacios en blanco se refieren a espacios, tabulaciones, avances de página, avances de línea y otros caracteres de espacios en blanco Unicode. Equivalente al conjunto de caracteres [^ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004​\u2005\u2006​\u2007\u2008​\u2009 \u200a ​\u2028\u2029​\u202f\u205f​\u3000].
[\b]Le permite encontrar el carácter de retroceso (carácter especial \b, U+0008).
\0 Le permite encontrar el símbolo 0 (cero).
\norteLe permite encontrar el carácter de nueva línea.
\FLe permite encontrar el carácter de avance de página.
\rLe permite encontrar el carácter de retorno de carro.
\ tLe permite encontrar el carácter de tabulación horizontal.
\vLe permite encontrar el carácter de tabulación vertical.
\wLe permite buscar cualquier carácter alfanumérico en el alfabeto latino básico, incluidos los guiones bajos. Equivalente al conjunto de caracteres.
\WLe permite encontrar cualquier carácter que no sea un carácter del alfabeto latino básico. Equivalente al juego de caracteres [^a-Za-z0-9_].
\cXLe permite encontrar un carácter de control en una cadena. Donde X es la letra de la A a la Z. Por ejemplo, /\cM/ representa el carácter Ctrl-M.
\xhhLe permite buscar un carácter usando un valor hexadecimal (hh es un valor hexadecimal de dos dígitos).
\uhhhhLe permite buscar un carácter utilizando la codificación UTF-16 (hhhh es un valor hexadecimal de cuatro dígitos).
\u(hhhh) o
\u(hhhhh)
Le permite buscar un carácter con un valor Unicode de U+hhhh o U+hhhhh (valor hexadecimal). Sólo cuando se da la bandera u.
\ Indica que el siguiente carácter es especial y no debe interpretarse literalmente. Para caracteres que normalmente se interpretan de forma especial, especifica que el siguiente carácter no es especial y debe interpretarse literalmente.

Restricciones

Cuantificadores

SímboloBandera
norte*La coincidencia se produce en cualquier cadena que contenga cero o más apariciones del carácter. norte.
norte+La coincidencia se produce con cualquier cadena que contenga al menos un carácter. norte.
¿norte?La coincidencia se produce en cualquier cadena con un elemento anterior. norte cero o una vez.
norte(x)Coincide con cualquier cadena que contenga una secuencia de caracteres norte un cierto número de veces incógnita. incógnita
norte(x,) incógnita apariciones del elemento anterior norte. incógnita debe ser un número entero positivo.
norte(x,y)Coincide con cualquier cadena que contenga al menos incógnita, pero no más que con y apariciones del elemento anterior norte. incógnita Y y deben ser números enteros positivos.
norte*?
n+?
¿¿norte??
n(x)?
n(x,)?
n(x,y)?
La comparación se produce por analogía con los cuantificadores *, +, ? y (...), sin embargo, la búsqueda es por la mínima comparación posible. El valor predeterminado es el modo "codicioso". al final del cuantificador le permite establecer un modo "no codicioso" en el que la comparación se repite el mínimo número posible de veces.
x(?=y)Le permite comparar incógnita, sólo si por incógnita debería y.
x(?!y)Le permite comparar incógnita, sólo si por incógnita no debería y.
x|yLa comparación se produce con cualquiera de las alternativas especificadas.

Agrupación y vínculos de retroceso

SímboloBandera
(incógnita)Le permite encontrar un símbolo. incógnita y recordar el resultado de la comparación ("capturar paréntesis"). La subcadena coincidente se puede llamar desde los elementos de la matriz resultante..., [n], o desde las propiedades del objeto RegExp predefinido $1..., $9.
(?:incógnita)Le permite encontrar un símbolo. incógnita, pero no recuerda el resultado del partido ("paréntesis de no captura"). La subcadena coincidente no se puede llamar desde los elementos de matriz resultantes..., [n], ni desde las propiedades del objeto RegExp predefinido $1..., $9.
\norteUna referencia de retorno a la última subcadena que coincide con la enésima entre paréntesis en una expresión regular (la numeración de paréntesis va de izquierda a derecha). norte debe ser un número entero positivo.

Algunas personas, cuando se enfrentan a un problema, piensan: "Oh, usaré expresiones regulares". Ahora tienen dos problemas.
Jamie Zawinski

Yuan-Ma dijo: “Se necesita mucha fuerza para cortar madera a lo largo de la veta de la madera. Se necesita mucho código para programar toda la estructura del problema.
Maestro Yuan-Ma, “Libro de Programación”

Las herramientas y técnicas de programación sobreviven y se difunden de una manera evolutiva caótica. A veces no sobreviven las bellas y brillantes, sino simplemente aquellas que funcionan lo suficientemente bien en su campo, por ejemplo, si se integran en otra tecnología exitosa.

En este capítulo, analizaremos dicha herramienta: las expresiones regulares. Esta es una forma de describir patrones en datos de cadenas. Crean un lenguaje pequeño e independiente que se incluye en JavaScript y muchos otros lenguajes y herramientas.

Los horarios habituales son muy extraños y extremadamente útiles. Su sintaxis es críptica y su interfaz de programación JavaScript es torpe. Pero es una herramienta poderosa para explorar y manipular cuerdas. Una vez que los comprenda, se convertirá en un programador más eficaz.

Creando una expresión regular

Regular: tipo de objeto. Se puede crear llamando al constructor RegExp o escribiendo la plantilla deseada, rodeada de barras.

Var re1 = nueva RegExp("abc"); var re2 = /abc/;

Ambas expresiones regulares representan el mismo patrón: el carácter "a" seguido del carácter "b" seguido del carácter "c".

Si utiliza el constructor RegExp, entonces el patrón se escribe como una cadena normal, por lo que se aplican todas las reglas relativas a las barras invertidas.

La segunda entrada, donde el patrón está entre barras, maneja las barras invertidas de manera diferente. Primero, dado que el patrón termina con una barra diagonal, debemos colocar una barra invertida antes de la barra diagonal que queremos incluir en nuestro patrón. Además, las barras invertidas que no forman parte de caracteres especiales como \n se conservarán (en lugar de ignorarse como en las cadenas) y cambiarán el significado del patrón. Algunos caracteres, como el signo de interrogación o el signo más, tienen un significado especial en las expresiones regulares y, si necesita hacer coincidir dicho carácter, también debe ir precedido de una barra invertida.

Var dieciochoMás = /dieciocho\+/;

Para saber qué caracteres deben ir precedidos por una barra diagonal, debe aprender una lista de todos los caracteres especiales en las expresiones regulares. Esto todavía no es posible, así que en caso de duda, simplemente coloque una barra invertida delante de cualquier carácter que no sea una letra, un número o un espacio.

Comprobando coincidencias

Los habituales tienen varios métodos. La más sencilla es la prueba. Si le pasa una cadena, devolverá un valor booleano que indica si la cadena contiene una aparición del patrón dado.

Console.log(/abc/.test("abcde")); // → verdadero console.log(/abc/.test("abxde")); // → falso

Una secuencia regular que consta únicamente de caracteres no especiales es simplemente una secuencia de estos caracteres. Si abc está en cualquier parte de la línea que estamos probando (no solo al principio), la prueba devolverá verdadero.

Buscando un conjunto de personajes

También puedes averiguar si una cadena contiene abc usando indexOf. Los patrones regulares te permiten ir más allá y crear patrones más complejos.

Digamos que necesitamos encontrar cualquier número. Cuando ponemos un conjunto de caracteres entre corchetes en una expresión regular, significa que esa parte de la expresión coincide con cualquiera de los caracteres entre corchetes.

Ambas expresiones están en líneas que contienen un número.

Console.log(//.test("en 1992")); // → verdadero console.log(//.test("en 1992")); // → verdadero

Entre corchetes, se utiliza un guión entre dos caracteres para especificar un rango de caracteres, donde la secuencia se especifica mediante la codificación Unicode. Los caracteres del 0 al 9 están en una fila (códigos del 48 al 57), por lo que los captura a todos y coincide con cualquier número.

Varios grupos de caracteres tienen sus propias abreviaturas integradas.

\d cualquier número
\w Carácter alfanumérico
\s Carácter de espacio en blanco (espacio, tabulación, nueva línea, etc.)
\D no es un número
\W no es un carácter alfanumérico
\S no es un carácter de espacio en blanco
. cualquier carácter excepto avance de línea

Por lo tanto, puede configurar el formato de fecha y hora como 30/01/2003 15:20 con la siguiente expresión:

Var fechaHora = /\d\d-\d\d-\d\d\d\d \d\d:\d\d/; console.log(dateTime.test("30-01-2003 15:20")); // → verdadero console.log(dateTime.test("30-ene-2003 15:20")); // → falso

Parece terrible, ¿no? Hay demasiadas barras invertidas, lo que dificulta la comprensión del patrón. Lo mejoraremos un poco más adelante.

Las barras invertidas también se pueden utilizar entre corchetes. Por ejemplo, [\d.] significa cualquier número o período. Observe que el punto dentro de los corchetes pierde su significado especial y se convierte simplemente en un punto. Lo mismo se aplica a otros caracteres especiales, como por ejemplo +.

Puede invertir un conjunto de caracteres, es decir, digamos que necesita encontrar cualquier carácter excepto los que están en el conjunto, colocando un signo ^ inmediatamente después del corchete de apertura.

Var notBinary = /[^01]/; console.log(notBinary.test("1100100010100110")); // → falso console.log(notBinary.test("1100100010200110")); // → verdadero

Repetir partes de la plantilla.

Sabemos cómo encontrar un número. ¿Qué pasa si necesitamos encontrar el número entero, una secuencia de uno o más dígitos?

Si pones un signo + después de algo en la secuencia regular, esto significará que ese elemento se puede repetir más de una vez. /\d+/ significa uno o más dígitos.

Console.log(/"\d+"/.test(""123"")); // → verdadero console.log(/"\d+"/.test("""")); // → falso console.log(/"\d*"/.test(""123"")); // → verdadero console.log(/"\d*"/.test("""")); // → verdadero

El asterisco * tiene casi el mismo significado, pero permite que el patrón aparezca cero veces. Si algo va seguido de un asterisco, nunca impide que el patrón esté en la línea; simplemente aparece allí cero veces.

Un signo de interrogación hace que parte del patrón sea opcional, lo que significa que puede aparecer cero o una vez. En el siguiente ejemplo, puede aparecer el carácter u, pero el patrón coincide incluso cuando no es así.

Var vecino = /vecino?r/; console.log(vecino.test("vecino")); // → verdadero console.log(vecino.test("vecino")); // → verdadero

Las llaves se utilizan para especificar el número exacto de veces que debe ocurrir un patrón. (4) después de un elemento significa que debe aparecer 4 veces en la línea. También puede especificar un espacio: (2,4) significa que el elemento debe aparecer al menos 2 y no más de 4 veces.

Otra versión del formato de fecha y hora, donde se permiten días, meses y horas de uno o dos dígitos. Y también es un poco más legible.

Var fechaHora = /\d(1,2)-\d(1,2)-\d(4) \d(1,2):\d(2)/; console.log(dateTime.test("30-1-2003 8:45")); // → verdadero

Puede utilizar espacios abiertos omitiendo uno de los números. (,5,) significa que el patrón puede ocurrir de cero a cinco veces, y (5,) significa de cinco o más.

Agrupación de subexpresiones

Para utilizar los operadores * o + en varios elementos a la vez, puede utilizar paréntesis. La parte de la expresión regular entre corchetes se considera un elemento desde el punto de vista de los operadores.

Var caricaturaLlorando = /boo+(hoo+)+/i; console.log(cartoonCrying.test("Boohoooohoohooo")); // → verdadero

Las ventajas primera y segunda solo se aplican a la segunda o en boo y hoo. El tercer + se refiere a todo el grupo (hoo+), encontrando una o más de esas secuencias.

La letra i al final de la expresión hace que la expresión regular no distinga entre mayúsculas y minúsculas, de modo que B coincida con b.

Partidos y grupos

El método de prueba es el método más sencillo para comprobar expresiones regulares. Sólo le indica si se encontró una coincidencia o no. Los regulares también tienen un método ejecutivo, que devolverá nulo si no se encuentra nada y, en caso contrario, devolverá un objeto con información sobre la coincidencia.

Coincidencia de var = /\d+/.exec("uno dos 100"); console.log(coincidencia); // → ["100"] console.log(match.index); // → 8

El objeto devuelto por exec tiene una propiedad de índice, que contiene el número del carácter a partir del cual se produjo la coincidencia. En general, el objeto parece una matriz de cadenas, donde el primer elemento es la cadena cuya coincidencia se comprobó. En nuestro ejemplo, esta será la secuencia de números que estábamos buscando.

Las cadenas tienen un método de coincidencia que funciona prácticamente de la misma manera.

Console.log("uno dos 100".match(/\d+/)); // → ["100"]

Cuando una expresión regular contiene subexpresiones agrupadas por paréntesis, el texto que coincida con estos grupos también aparecerá en la matriz. El primer elemento es siempre una coincidencia completa. La segunda es la parte que coincidió con el primer grupo (aquel cuyos paréntesis se encontraron primero), luego el segundo grupo, y así sucesivamente.

Var quotedText = /"([^"]*)"/; console.log(quotedText.exec("ella dijo "hola"")); // → [""hola"", "hola"]

Cuando no se encuentra ningún grupo (por ejemplo, si va seguido de un signo de interrogación), su posición en la matriz no está definida. Si un grupo coincide varias veces, solo la última coincidencia estará en la matriz.

Console.log(/bad(ly)?/.exec("malo")); // → ["malo", indefinido] console.log(/(\d)+/.exec("123")); // → ["123", "3"]

Los grupos son útiles para recuperar partes de cadenas. Si no solo queremos verificar si una cadena tiene una fecha, sino extraerla y crear un objeto que represente la fecha, podemos encerrar las secuencias de números entre paréntesis y seleccionar la fecha del resultado de exec.

Pero primero, una pequeña digresión en la que aprenderemos la forma preferida de almacenar la fecha y la hora en JavaScript.

Tipo de fecha

JavaScript tiene un tipo de objeto estándar para fechas, más específicamente, momentos en el tiempo. Se llama Fecha. Si simplemente crea un objeto de fecha usando nuevo, obtendrá la fecha y hora actuales.

Console.log(nueva fecha()); // → domingo 9 de noviembre de 2014 00:07:57 GMT+0300 (CET)

También puedes crear un objeto que contenga un tiempo determinado.

Console.log (nueva fecha (2015, 9, 21)); // → Miércoles 21 de octubre de 2015 00:00:00 GMT+0300 (CET) console.log(nueva fecha(2009, 11, 9, 12, 59, 59, 999)); // → miércoles 9 de diciembre de 2009 12:59:59 GMT+0300 (CET)

JavaScript utiliza una convención en la que los números de mes comienzan con cero y los números de día comienzan con uno. Esto es estúpido y ridículo. Ten cuidado.

Los últimos cuatro argumentos (horas, minutos, segundos y milisegundos) son opcionales y se ponen a cero si faltan.

Las marcas de tiempo se almacenan como el número de milisegundos que han transcurrido desde principios de 1970. Para épocas anteriores a 1970, se utilizan números negativos (esto se debe a la convención de tiempo de Unix que se creó en esa época). El método getTime del objeto de fecha devuelve este número. Es naturalmente grande.
console.log(nueva fecha(2013, 11, 19).getTime()); // → 1387407600000 console.log(nueva fecha(1387407600000)); // → Jueves 19 de diciembre de 2013 00:00:00 GMT+0100 (CET)

Si le da un argumento al constructor de fecha, se trata como este número de milisegundos. Puede obtener el valor actual de milisegundos creando un objeto Date y llamando al método getTime, o llamando a la función Date.now.

El objeto Date tiene métodos getFullYear, getMonth, getDate, getHours, getMinutes y getSeconds para recuperar sus componentes. También hay un método getYear que devuelve un código de dos dígitos bastante inútil como 93 o 14.

Al encerrar las partes relevantes de la plantilla entre paréntesis, podemos crear un objeto de fecha directamente a partir de una cadena.

Función findDate(string) ( var dateTime = /(\d(1,2))-(\d(1,2))-(\d(4))/; var match = dateTime.exec(string); return nueva Fecha(Número(coincidencia), Número(coincidencia) - 1, Número(coincidencia) ) console.log(findDate("30-1-2003")); // → Jueves 30 de enero de 2003 00:00:00 GMT+0100 (CET)

Límites de palabras y líneas

Desafortunadamente, findDate extraerá con la misma facilidad la fecha sin sentido 00-1-3000 de la cadena "100-1-30000". La coincidencia puede ocurrir en cualquier parte de la cadena, por lo que en este caso simplemente comenzará en el segundo carácter y terminará en el penúltimo carácter.

Si necesitamos forzar la coincidencia para que tome toda la cadena, usamos las etiquetas ^ y $. ^ coincide con el principio de la línea y $ coincide con el final. Por lo tanto, /^\d+$/ coincide con una cadena que contiene solo uno o más dígitos, /^!/ coincide con una cadena que comienza con un signo de exclamación y /x^/ no coincide con ninguna cadena (no puede haber una x).

Si, por otro lado, solo queremos asegurarnos de que la fecha comience y termine en el límite de una palabra, usamos la marca \b. Un límite de palabra puede ser el principio o el final de una línea, o cualquier lugar de una línea donde haya un carácter alfanumérico \w en un lado y un carácter no alfanumérico en el otro.

Console.log(/cat/.test("concatenar")); // → verdadero console.log(/\bcat\b/.test("concatenar")); // → falso

Tenga en cuenta que la etiqueta de límite no es un símbolo. Es simplemente una restricción que significa que una coincidencia sólo ocurre si se cumple una determinada condición.

Plantillas con elección

Digamos que necesita averiguar si el texto contiene no solo un número, sino un número seguido de cerdo, vaca o pollo en singular o plural.

Sería posible escribir tres expresiones regulares y comprobarlas una por una, pero hay una forma mejor. Símbolo | denota una elección entre los patrones a la izquierda y a la derecha del mismo. Y podemos decir lo siguiente:

Var animalCount = /\b\d+ (cerdo|vaca|pollo)s?\b/; console.log(animalCount.test("15 cerdos")); // → verdadero console.log(animalCount.test("15 cerdopollos")); // → falso

Los paréntesis delimitan la parte del patrón a la que se aplica | y muchos de estos operadores se pueden colocar uno tras otro para indicar una elección entre más de dos opciones.

Motor de búsqueda

Las expresiones regulares pueden considerarse diagramas de flujo. El siguiente diagrama describe un ejemplo reciente de ganadería.

Una expresión coincide con una cadena si es posible encontrar una ruta desde el lado izquierdo del diagrama hacia la derecha. Recordamos la posición actual en la línea, y cada vez que recorremos el rectángulo, verificamos que la parte de la línea inmediatamente después de nuestra posición coincida con el contenido del rectángulo.

Esto significa que verificar si nuestro carácter normal coincide con la cadena "los 3 cerdos" cuando revisamos el diagrama de flujo se ve así:

En la posición 4 hay un límite de palabra y pasamos el primer rectángulo.
- comenzando desde la 4ª posición encontramos el número y pasamos por el segundo rectángulo
- en la posición 5, un camino se cierra delante del segundo rectángulo y el segundo va más allá del rectángulo con un espacio. Tenemos un espacio, no un número, y elegimos el segundo camino.
- ahora estamos en la posición 6, el comienzo de los “cerdos”, y en la triple bifurcación de los caminos. No hay “vaca” ni “pollo” en la fila, pero sí “cerdo”, así que elegimos este camino.
- en la posición 9 después de la triple bifurcación, un camino pasa por alto "s" y va al último rectángulo con un límite de palabra, y el segundo pasa por "s". Tenemos una "s", así que vamos allí.
- en la posición 10 estamos al final de la línea y solo el límite de la palabra puede coincidir. El final de la línea se considera el límite y pasamos por el último rectángulo. Y ahora hemos encontrado con éxito nuestra plantilla.

Básicamente, la forma en que funcionan las expresiones regulares es que el algoritmo comienza al principio de la cadena e intenta encontrar una coincidencia allí. En nuestro caso, hay un límite de palabra, por lo que pasa por el primer rectángulo, pero no hay ningún número allí, por lo que se topa con el segundo rectángulo. Luego pasa al segundo carácter de la cadena e intenta encontrar una coincidencia allí... Y así sucesivamente hasta que encuentra una coincidencia o llega al final de la cadena, en cuyo caso no se encuentra ninguna coincidencia.

Sobornos

La expresión regular /\b(+b|\d+|[\da-f]h)\b/ coincide con un número binario seguido de una b, un número decimal sin sufijo o un número hexadecimal (los números del 0 al 9 o los símbolos de la a a la h), seguidos de h. Diagrama relevante:

Al buscar una coincidencia, puede suceder que el algoritmo tome la ruta superior (número binario), incluso si no existe tal número en la cadena. Si hay una línea “103”, por ejemplo, está claro que sólo después de llegar al número 3 el algoritmo entenderá que está en el camino equivocado. En general, la línea coincide con la secuencia regular, pero no en este hilo.

Luego el algoritmo retrocede. En una bifurcación, recuerda la posición actual (en nuestro caso, este es el comienzo de la línea, justo después del límite de la palabra) para que puedas regresar e intentar otro camino si el elegido no funciona. Para la cadena "103", después de encontrar un tres, retrocederá e intentará seguir la ruta decimal. Esto funcionará para que se encuentre una coincidencia.

El algoritmo se detiene tan pronto como encuentra una coincidencia completa. Esto significa que incluso si varias opciones pueden ser adecuadas, sólo se utiliza una de ellas (en el orden en que aparecen en la secuencia habitual).

El retroceso se produce cuando se utilizan operadores de repetición como + y *. Si busca /^.*x/ en la cadena "abcxe", la parte de la expresión regular.* intentará consumir toda la cadena. Entonces el algoritmo se dará cuenta de que también necesita "x". Como no hay una "x" después del final de la cadena, el algoritmo intentará buscar una coincidencia retrocediendo un carácter. Después de abcx tampoco hay x, luego se revierte nuevamente, esta vez a la subcadena abc. Y después de la línea, encuentra x e informa una coincidencia exitosa, en las posiciones 0 a 4.

Puede escribir una rutina regular que dará lugar a múltiples reversiones. Este problema ocurre cuando el patrón puede coincidir con la entrada de muchas maneras diferentes. Por ejemplo, si cometemos un error al escribir la expresión regular para números binarios, podríamos escribir accidentalmente algo como /(+)+b/.

Si el algoritmo buscara ese patrón en una larga cadena de 0 y 1 que no tuviera una "b" al final, primero pasaría por el bucle interno hasta que se quedara sin dígitos. Luego se dará cuenta de que no hay "b" al final, retrocederá una posición, pasará por el bucle exterior, se rendirá de nuevo, intentará retroceder a otra posición a lo largo del bucle interior... Y continuará para buscar de esta manera, usando ambos bucles. Es decir, la cantidad de trabajo con cada carácter de la línea se duplicará. Incluso para varias docenas de personajes, encontrar una coincidencia llevará mucho tiempo.

método de reemplazo

Las cadenas tienen un método de reemplazo que puede reemplazar parte de una cadena con otra cadena.

Console.log("papá".replace("p", "m")); // → mapa

El primer argumento también puede ser una expresión regular, en cuyo caso se reemplaza la primera aparición de la expresión regular en la línea. Cuando se agrega la opción "g" (global) a una expresión regular, se reemplazan todas las apariciones, no solo la primera.

Console.log("Borobudur".replace(//, "a")); // → Barobudur console.log("Borobudur".replace(//g, "a")); // → Barabadar

Tendría sentido pasar la opción "reemplazar todo" a través de un argumento separado o mediante un método separado como reemplazarTodo. Pero, lamentablemente, la opción se transmite a través del propio sistema normal.

Todo el poder de las expresiones regulares se revela cuando usamos enlaces a grupos que se encuentran en una cadena, especificada en la expresión regular. Por ejemplo, tenemos una línea que contiene los nombres de las personas, un nombre por línea, en el formato "Apellido, Nombre". Si necesitamos intercambiarlos y quitar la coma para obtener “Nombre Apellido”, escribimos lo siguiente:

Console.log("Hopper, Grace\nMcCarthy, John\nRitchie, Dennis" .replace(/([\w ]+), ([\w ]+)/g, "$2 $1")); // → Grace Hopper // John McCarthy // Dennis Ritchie

$1 y $2 en la línea de reemplazo se refieren a grupos de caracteres entre paréntesis. $1 se reemplaza con el texto que coincide con el primer grupo, $2 con el segundo grupo, y así sucesivamente, hasta $9. La coincidencia completa está contenida en la variable $&.

También puede pasar una función como segundo argumento. Para cada reemplazo, se llamará una función cuyos argumentos serán los grupos encontrados (y toda la parte coincidente de la línea), y su resultado se insertará en una nueva línea.

Ejemplo sencillo:

Var s = "la cia y el fbi"; console.log(s.replace(/\b(fbi|cia)\b/g, function(str) ( return str.toUpperCase(); ))); // → la CIA y el FBI

Aquí hay uno más interesante:

Var caldo = "1 limón, 2 coles y 101 huevos"; función menosUno(coincidencia, cantidad, unidad) ( cantidad = Número(cantidad) - 1; if (cantidad == 1) // solo queda uno, elimina la "s" al final unidad = unidad.slice(0, unidad. longitud - 1); else if (cantidad == 0) cantidad = "no"; cantidad devuelta + " " + unidad ) console.log(stock.replace(/(\d+) (\w+)/g, minusOne) ); // → sin limón, 1 repollo y 100 huevos

El código toma una cadena, busca todas las apariciones de números seguidos de una palabra y devuelve una cadena con cada número reducido en uno.

El grupo (\d+) va al argumento de cantidad y (\w+) va al argumento de unidad. La función convierte la cantidad en un número, y esto siempre funciona, porque nuestro patrón es \d+. Y luego realiza cambios en la palabra, en caso de que solo quede 1 elemento.

Codicia

Es fácil de usar reemplazar para escribir una función que elimine todos los comentarios del código JavaScript. Aquí está el primer intento:

Función stripComments(código) ( código de retorno.replace(/\/\/.*|\/\*[^]*\*\//g, ""); ) console.log(stripComments("1 + /* 2 */3")); // → 1 + 3 console.log(stripComments("x = 10;// ¡diez!")); // → x = 10; console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 1

La parte anterior al operador "o" coincide con dos barras seguidas de cualquier número de caracteres excepto nuevas líneas. La parte que elimina comentarios de varias líneas es más compleja. Usamos [^], es decir cualquier carácter que no esté vacío como forma de encontrar cualquier carácter. No podemos usar un punto porque los comentarios del bloque continúan en una nueva línea y el carácter de nueva línea no coincide con el punto.

Pero el resultado del ejemplo anterior es incorrecto. ¿Por qué?

La parte [^]* primero intentará capturar tantos caracteres como pueda. Si debido a esto la siguiente parte de la secuencia regular no encuentra una coincidencia, retrocederá un carácter y volverá a intentarlo. En el ejemplo, el algoritmo intenta capturar toda la línea y luego retrocede. Habiendo retrocedido 4 caracteres, encontrará */ en la línea, y esto no es lo que queríamos. Queríamos capturar solo un comentario y no ir al final de la línea y encontrar el último comentario.

Debido a esto, decimos que los operadores de repetición (+, *, ? y ()) son codiciosos, lo que significa que primero toman todo lo que pueden y luego regresan. Si coloca una pregunta después de un operador como este (+?, *?, ??, (?), se volverán no codiciosos y comenzarán a encontrar las ocurrencias más pequeñas posibles.

Y eso es lo que necesitamos. Al forzar el asterisco a buscar coincidencias en el mínimo número posible de caracteres en una línea, consumimos solo un bloque de comentarios y nada más.

Función stripComments(código) ( return code.replace(/\/\/.*|\/\*[^]*?\*\//g, ""); ) console.log(stripComments("1 /* a */+/* b */ 1")); // → 1 + 1

Se producen muchos errores al utilizar operadores codiciosos en lugar de operadores no codiciosos. Cuando utilice el operador de repetición, considere siempre primero el operador no codicioso.

Crear dinámicamente objetos RegExp

En algunos casos, el patrón exacto se desconoce en el momento en que se escribe el código. Por ejemplo, deberá buscar el nombre del usuario en el texto y encerrarlo entre guiones bajos. Dado que sólo sabrá el nombre después de ejecutar el programa, no puede utilizar la notación de barra diagonal.

Pero puedes construir la cadena y usar el constructor RegExp. He aquí un ejemplo:

Nombre var = "harry"; var text = "Y Harry tiene una cicatriz en la frente."; var regexp = new RegExp("\\b(" + nombre + ")\\b", "gi"); console.log(text.replace(regexp, "_$1_")); // → Y _Harry_ tiene una cicatriz en la frente.

Al crear límites de palabras, tenemos que usar barras dobles porque las escribimos en una línea normal y no en una secuencia regular con barras diagonales. El segundo argumento de RegExp contiene opciones para expresiones regulares; en nuestro caso, "gi", es decir. global y no distingue entre mayúsculas y minúsculas.

¿Pero qué pasa si el nombre es “dea+hlrd” (si nuestro usuario es un kulhatzker)? Como resultado, obtendremos una expresión regular sin sentido que no encontrará coincidencias en la cadena.

Podemos agregar barras invertidas antes de cualquier carácter que no nos guste. No podemos agregar barras invertidas antes de las letras porque \b o \n son caracteres especiales. Pero puedes agregar barras antes de cualquier carácter no alfanumérico sin ningún problema.

Nombre var = "dea+hlrd"; var text = "Esta dea+hlrd está molestando a todos."; var escapó = nombre.replace(/[^\w\s]/g, "\\$&"); var expresión regular = new RegExp("\\b(" + escape + ")\\b", "gi"); console.log(text.replace(regexp, "_$1_")); // → Esta _dea+hlrd_ molestó a todos.

método de búsqueda

El método indexOf no se puede utilizar con expresiones regulares. Pero hay un método de búsqueda que sólo espera expresiones regulares. Al igual que indexOf, devuelve el índice de la primera aparición, o -1 si no ocurre ninguna.

Console.log(" palabra".search(/\S/)); // → 2 console.log(" ".search(/\S/)); // → -1

Desafortunadamente, no hay manera de decirle al método que busque una coincidencia comenzando en un desplazamiento específico (como se puede hacer con indexOf). Eso sería útil.

propiedad último índice

El método exec tampoco proporciona una manera conveniente de iniciar una búsqueda desde una posición determinada en la cadena. Pero da una manera inconveniente.

Un objeto regex tiene propiedades. Uno de ellos es la fuente, que contiene una cadena. Otro es lastIndex, que controla, bajo algunas condiciones, dónde comenzará la próxima búsqueda de ocurrencias.

Estas condiciones incluyen que la opción global g debe estar presente y que la búsqueda debe realizarse utilizando el método exec. Una solución más razonable sería simplemente permitir que se pase un argumento adicional al ejecutivo, pero la razonabilidad no es una característica fundamental de la interfaz de expresiones regulares de JavaScript.

Patrón var = /y/g; patrón.lastIndex = 3; var coincidencia = patrón.exec("xyzzy"); console.log(match.index); // → 4 console.log(pattern.lastIndex); // → 5

Si la búsqueda fue exitosa, la llamada ejecutiva actualiza la propiedad lastIndex para que apunte a la posición después de la ocurrencia encontrada. Si no hubo éxito, lastIndex se establece en cero, al igual que el lastIndex del objeto recién creado.

Cuando se utiliza una variable regular global y varias llamadas ejecutivas, estas actualizaciones automáticas de lastIndex pueden causar problemas. Su servicio habitual puede iniciar la búsqueda desde la posición que quedó de la llamada anterior.

Var dígito = /\d/g; console.log(digit.exec("aquí está: 1")); // → ["1"] console.log(digit.exec("y ahora: 1")); // → nulo

Otro efecto interesante de la opción g es que cambia el funcionamiento del método de coincidencia. Cuando se llama con esta opción, en lugar de devolver una matriz similar al resultado de exec, busca todas las apariciones del patrón en la cadena y devuelve una matriz de las subcadenas encontradas.

Console.log("Banana".match(/an/g)); // → ["una", "una"]

Así que tenga cuidado con las variables regulares globales. Los casos en los que son necesarios (reemplazar llamadas o lugares donde usa específicamente lastIndex) son probablemente todos los casos en los que deberían usarse.

Ciclos de ocurrencia

Una tarea típica es iterar a través de todas las apariciones de un patrón en una cadena para que pueda acceder al objeto coincidente en el cuerpo del bucle usando lastIndex y exec.

Var input = "Una línea con 3 números... 42 y 88."; número var = /\b(\d+)\b/g; coincidencia de var; while (match = number.exec(input)) console.log("Encontrado", match, " on ", match.index); // → Encontrado 3 por 14 // Encontrado 42 por 33 // Encontrado 88 por 40

Aprovecha el hecho de que el valor de la asignación es el valor que se asigna. Al usar match = re.exec(input) como condición en un bucle while, buscamos al comienzo de cada iteración, almacenamos el resultado en una variable y finalizamos el bucle cuando se encuentran todas las coincidencias.

Analizando archivos INI

Para concluir el capítulo, veamos un problema que utiliza expresiones regulares. Imaginemos que estamos escribiendo un programa que recopila información sobre nuestros enemigos a través de Internet de forma automática. (No escribiremos el programa completo, solo la parte que lee el archivo de configuración. Lo sentimos.) El archivo se ve así:

Searchengine=http://www.google.com/search?q=$1 rencor=9.7; se coloca un punto y coma antes de los comentarios; cada sección se refiere a un enemigo diferente fullname=Larry Doe type=kindergarten bull website=http://www.geocities.com/CapeCanaveral/11451 fullname=Gargamel type=hechicero malvado outputdir=/home/marijn/enemies/gargamel

El formato de archivo exacto (que se usa bastante y generalmente se llama INI) es el siguiente:

Se ignoran las líneas en blanco y las líneas que comienzan con punto y coma.
- las líneas entre corchetes comienzan una nueva sección
- líneas que contienen un identificador alfanumérico seguido de = agregar una configuración en esta sección

Todo lo demás son datos incorrectos.

Nuestra tarea es convertir dicha cadena en una matriz de objetos, cada uno con una propiedad de nombre y una matriz de configuraciones. Se necesita un objeto para cada sección y otro para la configuración global en la parte superior del archivo.

Dado que el archivo debe analizarse línea por línea, es una buena idea comenzar dividiendo el archivo en líneas. Para hacer esto, usamos string.split("\n") en el Capítulo 6. Algunos sistemas operativos no utilizan un carácter \n para los saltos de línea, sino dos: \r\n. Dado que el método de división toma expresiones regulares como argumento, podemos dividir líneas usando la expresión /\r?\n/, permitiendo \n y \r\n simples entre líneas.

Función parseINI(cadena) ( // Comencemos con un objeto que contiene configuraciones de nivel superior var currentSection = (nombre: nulo, campos: ); var categorías = ; string.split(/\r?\n/).forEach(function (línea) (var match; if (/^\s*(;.*)?$/.test(line)) (return;) else if (match = line.match(/^\[(.*)\ ]$ /)) ( currentSection = (nombre: coincidencia, campos: ); categorías.push(currentSection); ) else if (match = line.match(/^(\w+)=(.*)$/)) ( currentSection.fields.push((nombre: coincidencia, valor: coincidencia)); else ( throw new Error("La línea "" + línea + "" contiene datos no válidos."); ) ));

El código recorre todas las líneas, actualizando el objeto de la sección actual "sección actual". Primero, verifica si la línea se puede ignorar usando la expresión regular /^\s*(;.*)?$/. ¿Te imaginas cómo funciona esto? La parte entre paréntesis coincide con los comentarios, ¿eh? hace que el carácter normal también coincida con líneas que constan solo de espacios.

Si la línea no es un comentario, el código verifica si comienza una nueva sección. En caso afirmativo, crea un nuevo objeto para la sección actual, al que se agregan configuraciones posteriores.

La última posibilidad significativa es que la cadena sea una configuración normal, en cuyo caso se agrega al objeto actual.

Si ninguna de las opciones funciona, la función arroja un error.

Observe cómo el uso frecuente de ^ y $ garantiza que la expresión coincida con toda la cadena y no solo con una parte. Si no los usa, el código generalmente funcionará, pero a veces producirá resultados extraños y será difícil localizar el error.

La construcción if (match = string.match(...)) es similar al truco de usar la asignación como condición en un bucle while. A menudo no sabes si la llamada de coincidencia será exitosa, por lo que solo puedes acceder al objeto de resultado dentro de un bloque if que lo verifica. Para no romper la hermosa cadena de verificaciones if, asignamos el resultado de la búsqueda a una variable e inmediatamente usamos esta asignación como verificación.

Símbolos internacionales

Debido a la implementación inicialmente simple del lenguaje y la posterior fijación de dicha implementación "en granito", las expresiones regulares de JavaScript son estúpidas con caracteres que no se encuentran en el idioma inglés. Por ejemplo, el carácter "letra", desde el punto de vista de las expresiones regulares de JavaScript, puede ser una de las 26 letras del alfabeto inglés y, por alguna razón, también un guión bajo. Letras como é o β, que son claramente letras, no coinciden con \w (y coincidirán con \W, que no es una letra).

En un giro extraño, históricamente \s (espacio) coincide con todos los caracteres que se consideran espacios en blanco en Unicode, incluidos elementos como el espacio sin separación o el separador de vocales mongol.

Algunas implementaciones de expresiones regulares en otros idiomas tienen una sintaxis especial para buscar categorías especiales de caracteres Unicode, como "todo en mayúsculas", "todos los signos de puntuación" o "caracteres de control". Hay planes para agregar dichas categorías a JavaScript, pero aparentemente no se implementarán pronto.

En pocas palabras

Los regulares son objetos que representan patrones de búsqueda en cadenas. Usan su propia sintaxis para expresar estos patrones.

/abc/ Secuencia de caracteres
// Cualquier carácter de la lista
/[^abc]/ Cualquier carácter excepto los caracteres de la lista
// Cualquier carácter del intervalo
/x+/ Una o más apariciones del patrón x
/x+?/ Una o más apariciones, no codiciosas
/x*/ Cero o más apariciones
/x?/ Cero o una ocurrencia
/x(2,4)/ De dos a cuatro ocurrencias
/(abc)/ Grupo
/a|b|c/ Cualquiera de varios patrones
/\d/ Cualquier número
/\w/ Cualquier carácter alfanumérico (“letra”)
/\s/ Cualquier carácter de espacio en blanco
/./ Cualquier carácter excepto nuevas líneas
/\b/ Límite de palabra
/^/ Inicio de línea
/$/ Fin de línea

La expresión regular tiene un método de prueba para comprobar si el patrón está en la cadena. Existe un método ejecutivo que devuelve una matriz que contiene todos los grupos encontrados. La matriz tiene una propiedad de índice, que contiene el número del carácter a partir del cual se produjo la coincidencia.

Las cadenas tienen un método de coincidencia para hacer coincidir patrones y un método de búsqueda para devolver solo la posición inicial de la ocurrencia. El método de reemplazo puede reemplazar apariciones de un patrón con otra cadena. Además, puede pasar una función para reemplazar que creará una línea de reemplazo basada en la plantilla y los grupos encontrados.

Los caracteres normales tienen configuraciones que se escriben después de la barra de cierre. La opción i hace que la expresión regular no distinga entre mayúsculas y minúsculas, y la opción g la hace global, lo que, entre otras cosas, hace que el método de reemplazo reemplace todas las apariciones encontradas, no solo la primera.

El constructor RegExp se puede utilizar para crear expresiones regulares a partir de cadenas.

Los reguladores son un instrumento afilado con un mango incómodo. Simplifican enormemente algunas tareas y pueden volverse inmanejables al resolver otros problemas complejos. Parte de aprender a usar expresiones regulares es ser capaz de resistir la tentación de rellenarlas con una tarea para la que no está destinada.

Ceremonias

Inevitablemente, al resolver problemas, encontrará casos incomprensibles y, a veces, puede desesperarse al ver el comportamiento impredecible de algunas expresiones regulares. A veces ayuda estudiar el comportamiento de un motor normal a través de un servicio online como debuggex.com, donde se puede ver su visualización y compararlo con el efecto deseado.
Golf regular
"Golf" en código es un juego en el que es necesario expresar un programa determinado en un número mínimo de caracteres. El golf regular es un ejercicio práctico para escribir los regulares más pequeños posibles para encontrar un patrón determinado, y solo eso.

Para cada una de las sublíneas, escriba una expresión regular para verificar su ubicación en la línea. El motor normal debería encontrar sólo estas subcadenas especificadas. No se preocupe por los límites de las palabras a menos que se mencionen específicamente. Cuando tenga un patrón regular que funcione, intente reducirlo.

coche y gato
- pop y utilería
- hurón, ferry y ferrari
- Cualquier palabra que termine en ious
- Un espacio seguido de un punto, coma, dos puntos o punto y coma.
- Una palabra de más de seis letras.
- Palabra sin letras e

// Ingresa tus expresiones regulares verificar(/.../, ["my car", "bad cats"], ["camper", "high art"]); verificar(/.../, ["cultura pop", "accesorios locos"], ["plop"]); verificar(/.../, ["hurón", "ferry", "ferrari"], ["ferrum", "transfer A"]); verificar(/.../, ["qué delicioso", "habitación espaciosa"], ["ruinoso", "conciencia"]); verificar(/.../, ["puntuación incorrecta."], ["escapar del punto"]); verificar(/.../, ["hottenottententen"], ["no", "hotten totten tenten"]); verificar(/.../, ["ornitorrinco rojo", "nido tambaleante"], ["cama de tierra", "simio que aprende"]); function verificar(regexp, yes, no) ( // Ignorar ejercicios sin terminar if (regexp.source == "...") return; yes.forEach(function(s) ( if (!regexp.test(s)) console .log("No encontrado "" + s + """ )); no.forEach(funciones) ( if (regexp.test(s)) console.log("Ocurrencia inesperada "" + s + " "" );

Citas en texto
Digamos que escribiste una historia y usaste comillas simples para indicar el diálogo. Ahora desea reemplazar las comillas del diálogo con comillas dobles y dejar las comillas simples en abreviaturas de palabras como not are.

Cree un patrón que distinga entre estos dos usos de comillas y escriba una llamada al método de reemplazo que realiza el reemplazo.

Números otra vez
Las secuencias de números se pueden encontrar con una simple expresión regular /\d+/.

Escribe una expresión que encuentre solo números escritos en estilo JavaScript. Debe admitir un posible menos o más antes del número, un punto decimal y notación científica 5e-3 o 1E10, nuevamente con un posible más o menos. También tenga en cuenta que puede que no necesariamente haya números antes o después del punto, pero el número no puede consistir en un solo punto. Es decir, 0,5 o 5 son números válidos, pero un punto por sí solo no lo es.

// Introduzca aquí la secuencia regular. número var = /^...$/; // Pruebas: ["1", "-1", "+15", "1.55", ".5", "5.", "1.3e2", "1E-4", "1e+12"] .forEach(function(s) ( if (!number.test(s)) console.log("No encontré "" + s + """); )); ["1a", "+-1", "1.2.3", "1+1", "1e4.5", ".5.", "1f5", "."].forEach(funciones) ( if (número.prueba(s)) console.log("Aceptado incorrectamente "" + s + """); ));

Las expresiones regulares o regulares son intimidantes para los principiantes, pero esenciales para cualquier programador. Entendamos las expresiones regulares usando 5 ejemplos simples con JavaScript.

Si tienes un problema y lo vas a resolver con expresiones regulares, ahora tienes dos problemas. Hay un dicho. Las expresiones regulares que se encuentran en el código a veces provocan miedo y odio en personas que no están familiarizadas con ellas.

Pero, de hecho, cualquier expresión regular es solo una expresión de plantilla que puede resolver el problema de una función completa en una línea. Sin embargo, para crear una expresión regular, es necesario tener en cuenta un conjunto de reglas estrictas en las que un principiante puede confundirse y cometer errores.

personajes coincidentes

Las expresiones regulares más básicas son aquellas que coinciden con caracteres individuales. Aquí están sus reglas:

1. Un punto (.) coincide con cualquier carácter. Si necesita buscar un punto específico, debe escapar usando el carácter “\” (\.).

2. Un signo de interrogación (?) indica que el carácter anterior es opcional. Para buscar el signo de interrogación en una cadena, también se debe utilizar como escape "\" (\?).

var text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit no sea que. Donec convallis dignissim ligula, et rutrum est elat vistibulum eu."; // Tanto "elit" como "elat" servirán. El punto significa que cualquier símbolo servirá. var expresión regular = /el.t/g; console.log(text.match(regex)); // "est" y "lest" funcionarán igualmente bien. El signo de interrogación hace que la "l" sea opcional. var regex2 = /l?est/g; console.log(text.match(regex2));

var texto = "Lorem ipsum dolor sit amet, consectetur adipiscing elit no sea. Donec convallis dignissim ligula, et rutrum est elat vistibulum eu".;

// Tanto "elit" como "elat" servirán. El punto significa que cualquier símbolo servirá.

var expresión regular = /el.t/g;

consola. log(text. match(regex));

// "est" y "lest" funcionarán igualmente bien. El signo de interrogación hace que la "l" sea opcional.

var regex2 = /l?est/g ;

consola. log(text.match(regex2));

Unir varios personajes

Un conjunto es uno o más caracteres entre paréntesis, por ejemplo. Esta expresión buscará solo ese conjunto de caracteres en una cadena; en este ejemplo, solo a, b o c. Por el contrario, puede buscar apariciones de cualquier símbolo excepto el símbolo “^”. [^abc] coincidirá con cualquier carácter que no sea a, b o c. También puede especificar un rango de caracteres o números, por ejemplo, .

Hay juegos de caracteres integrados que facilitan la escritura de expresiones regulares. Se llaman abreviaturas o taquigrafías. Por ejemplo, puedes escribir \D en su lugar. Hay abreviaturas para otros caracteres (incluidos números y guiones bajos): \w y \W, así como para espacios: \s y \S.

// Sólo funcionarán "cat" y "can", no "car". var text = "lata de coche para gato"; console.log(text.match(/ca/g)); // Todo pasará excepto cat y can (hay un símbolo ^) console.log(text.match(/ca[^tn]/g)); // Otro ejemplo donde solo pasarán números text = "Me gustaría 8 tazas de café, por favor."; console.log("Cuántas tazas: " + text.match(//g)); // Una forma más fácil usando el acceso directo \d console.log("Cuántas tazas: " + text.match(/\d/g)); // Pasa todo excepto los números console.log(text.match(/\D/g));

// Sólo funcionarán "cat" y "can", no "car".

var text = "lata de coche para gato";

consola. log(text.match(/ca/g));

// Pasa todo excepto cat y can (hay un símbolo ^)

consola. iniciar sesión (texto. coincidencia (/ca[^tn]/g));

// Otro ejemplo donde solo pasarán números

texto = "Quiero 8 tazas de café, por favor".;

consola. log ("Cuántas tazas: " + text . match (//g ) );

// Manera más fácil usando el atajo \d

consola. log("Cuántas tazas: " + text . match (/\d/g ) );

// Todo pasará excepto los números

consola. log(text. match(/\D/g));

Palabras coincidentes

En la mayoría de los casos, es necesario buscar palabras completas, no caracteres individuales. Esto se hace usando modificadores (+) y (-), que repiten un carácter o conjunto de caracteres.

Sumar (X) especifica el número exacto de repeticiones, (x, y): el rango (x e y son números).

Además, hay un patrón especial \b que coincide con los límites al final de las palabras.

var text = "Hola gente de 1974. Vengo del futuro. ¡En 2014 tenemos pistolas láser, patinetas flotantes y vivimos en la luna!"; // Encontrará años. \d+ coincidirá con uno o más caracteres var añoRegex = /\d+/g; console.log("Años: ", text.match(añoRegex)); // Encuentra todas las oraciones. Nuestras oraciones comienzan con mayúscula y terminan con un punto o signo de exclamación. var fraseRegex = /.+?(\.|!)/g; console.log("Oraciones: ", text.match(sentenceRegex)); // Encuentra todas las palabras que comienzan con "h". Tanto las mayúsculas como las minúsculas son adecuadas para nosotros, por lo que usamos el modificador i // \b para definir el límite de la palabra. var hPalabras = /\bh\w+/ig; console.log("Palabras H: ", text.match(Palabrash)); // Encuentra todas las palabras de 4 a 6 caracteres var findWords = /\b\w(4,6)\b/g; console.log("Palabras entre 4 y 6 caracteres: ", text.match(findWords)); // Buscar palabras de más de 5 caracteres console.log("Palabras de 5 caracteres o más: ", text.match(/\b\w(5,)\b/g)); // Encuentra palabras de exactamente 6 caracteres de longitud console.log("Palabras de exactamente 6 caracteres de longitud: ", text.match(/\b\w(6)\b/g));

var texto = "Hola gente de 1974. Vengo del futuro. ¡En 2014 tenemos pistolas láser, patinetas flotantes y vivimos en la luna!";

// Encontrará años. \d+ coincide con uno o más caracteres

var añoRegex = /\d+/g ;

consola. log("Años:", texto.match(yearRegex));

// Encuentra todas las oraciones. Nuestras oraciones comienzan con mayúscula y terminan con un punto o signo de exclamación.

var fraseRegex = /.+?(\.|!)/g ;

consola. log("Oraciones: ", text. match(sentenciaRegex));

// Encuentra todas las palabras que comienzan con "h". Tanto las mayúsculas como las minúsculas son adecuadas para nosotros, por lo que usamos el modificador i

// \b para determinar los límites de las palabras.

var hPalabras = /\bh\w+/i g ;

consola. log ("H Palabras: ", texto. coincidencia (hPalabras));

// Encuentra todas las palabras de 4 a 6 caracteres

var buscarPalabras = /\b\w(4,6)\b/g ;

consola. registro( "Palabras entre 4 y 6 caracteres: ", texto . coincidencia(buscarPalabras));

// Encuentra palabras de más de 5 caracteres

consola. log ("Palabras de 5 caracteres o más: ", text. match (/\b\w(5,)\b/g));

// Encuentra palabras de exactamente 6 caracteres

consola. registro( "Palabras de exactamente 6 caracteres: ", texto . partido (/\b\w(6)\b/g ) );

Validación de cadena completa

En JavaScript, estas expresiones se pueden utilizar para validar la entrada del usuario desde campos de texto. Para validar cadenas se utiliza una expresión regular, ligada al principio y al final de un fragmento de texto, utilizando para ello las expresiones ^ (principio de línea) y $ (fin de línea). Estos símbolos garantizan que el patrón que escriba abarque toda la longitud del texto y no solo coincida con una parte de él.

Además, en este caso, utilizamos el método test() del objeto regex, que devuelve verdadero o falso al probar si la expresión regular coincide con la cadena.

// Tenemos una serie de cadenas, busquemos links..com/", "123461", "https://site/?s=google", "http://not a valid url", "abc http: / /invalid.url/" ]; var regex = /^https?:\/\/[\w\/?.&-=]+$/; var urls = ; for(var i = 0; i< strings.length; i++){ if(regex.test(strings[i])){ // Валидная ссылка urls.push(strings[i]); } } console.log("Valid URLs: ", urls);

// Tenemos una serie de cadenas, busquemos los enlaces.

var cadenas = [

"https://sitio/" ,

"esto no es una URL",

"https://google.com/" ,

"123461" ,

"https://sitio/?s=google",

"http://no es una URL válida",

"abchttp://invalid.url/"

var expresión regular = / ^ https? : \ / \ / [ \ w \ / ? . & -= ] + $ / ;

var URL = ;

para (var i = 0 ; i< strings . length ; i ++ ) {

if (expresión regular. prueba (cadenas [i])) (

URL. empujar(cadenas[i]);

consola. log("URL válidas: ", URL);

Buscar y reemplazar

Otra tarea común que se facilita mediante el uso de expresiones regulares es buscar y reemplazar texto.




Arriba