Ejemplos de expresiones regulares de Javascript. Expresiones regulares de JavaScript. Uso práctico: procesamiento de correo electrónico

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 (/). 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 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 colocándolos en 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 caracteres especiales las clases pueden estar 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 después del símbolo (o símbolos) la repetición signo de interrogació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 la menor cantidad posible número 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". Por lo tanto, cuando se aplica el patrón /a|ab/ 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 encerrado 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:

Símbolos de expresión regular para seleccionar entre alternativas, agrupar y Enlaces 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étera. 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 caracteres correspondientes a este 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" que se encuentra en línea separada, 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. Funcionará 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 un carácter \w y un carácter \W, o entre un carácter \w y el inicio 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.
(?=p) 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 uno más, último elemento Gramáticas de 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 que creamos, 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 utilizando 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. Esto es muy oportunidad ú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, eche un vistazo a lo siguiente código de programa que analiza la 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 de índice y entrada, 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 delimitador 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 la posición en la línea en la que comenzar próxima 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 al respecto. información completa. Cuando se llama a exec() en una expresión regular que contiene la bandera 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 cosa graciosa que Java!"; var resultado; while((resultado = patrón.exec(texto)) != nulo) ( console.log("Encontrado "" + resultado + """ + " en la posición " + resultado.index + " ; la próxima búsqueda comenzará desde " + patrón.lastIndex);

Otro método del objeto RegExp es prueba(), que es mucho método más simple ejecutivo(). 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().

Este artículo cubre los conceptos básicos del uso de expresiones regulares en Javascript.

Introducción

¿Qué es una expresión regular?

Una expresión regular JS es una secuencia de caracteres que forma una regla de búsqueda. Esta regla se puede utilizar para buscar texto y reemplazarlo. En la práctica, una expresión regular puede incluso constar de un solo carácter, pero los patrones de búsqueda más complejos son más comunes.

En Javascript, las expresiones regulares también son objetos. Estos son patrones que se utilizan para hacer coincidir secuencias de caracteres en cadenas. Se utilizan en los métodos exec() y test() del objeto RegExp, y en los métodos match(), replace(), search y split() del objeto String.

Ejemplo

patrón var = /ejemplo/i

/ejemplo/i es una expresión regular. El ejemplo es una plantilla ( que se utilizará en la búsqueda). i es un modificador que indica distinción entre mayúsculas y minúsculas.

Preparar una expresión regular

Las expresiones regulares JS constan de un patrón y un modificador. La sintaxis será algo como esto:

/patrón/modificadores;

La plantilla especifica la regla de búsqueda. Consta de caracteres simples como /abc/ o una combinación de caracteres simples y especiales: /abc/ o /Chapter (d+).d/ .

tabla de plantillas

Los modificadores le permiten hacer consultas que distingan entre mayúsculas y minúsculas, sean globales, etc. Se utilizan para realizar búsquedas que distinguen entre mayúsculas y minúsculas, así como búsquedas globales.

tabla de modificadores


Ahora estamos listos para aplicar expresiones regulares JS. Hay dos formas principales de hacer esto: usando un objeto de expresión regular o una expresión regular en una cadena.

Usando un objeto de expresión regular

Crear un objeto de expresión regular

Este objeto describe un patrón de carácter. Se utiliza para combinar patrones. Hay dos formas de construir un objeto de expresión regular.

Método 1: utilizar una expresión literal literal que consta de un patrón encerrado entre barras, por ejemplo:

var reg = /ab+c/;

Los literales de expresiones regulares activan la compilación previa de la expresión regular cuando se analiza el script. Si la expresión regular es constante, úsela para mejorar el rendimiento.

Método 2: llamar a la función constructora del objeto RegExp, por ejemplo:

var reg = nueva RegExp("ab+c");

El uso de un constructor permite compilar la expresión regular JS mientras se ejecuta el script. Utilice este método si la expresión regular va a cambiar o si no conoce el patrón de antemano. Por ejemplo, si recibe información de un usuario que ingresa una consulta de búsqueda.

Métodos de objetos de expresión regular

Echemos un vistazo a algunos métodos comunes de objetos de expresión regular:

  • compilar() ( obsoleto en la versión 1.5) – compila la expresión regular;
  • exec(): realiza una coincidencia de cadenas. Devuelve la primera coincidencia;
  • test(): realiza una coincidencia en una cadena. Devuelve verdadero o falso;
  • toString(): devuelve el valor de cadena de la expresión regular.

Ejemplos

Usando prueba()

El método test() es una expresión regular del objeto RegExp. Busca una cadena de patrón y devuelve verdadero o falso según el resultado. El siguiente ejemplo de expresión regular JS muestra cómo se busca en una cadena el carácter " mi”:

var patt = /e/; patt.test("¡Las mejores cosas del mundo son gratis!");

Ya que aquí en la fila hay “ mi”, el resultado de este código será verdadero.

Las expresiones regulares no tienen que colocarse en una variable. La misma consulta se puede realizar en una línea:

/e/.test("¡Las mejores cosas del mundo son gratis!");

Usando ejecutivo()

Busca una cadena usando una regla de búsqueda determinada y devuelve el texto encontrado. Si no se encontraron coincidencias, el resultado será nulo.

Veamos el método en acción, usando el ejemplo del mismo símbolo " mi”:

/e/.exec("¡Las mejores cosas del mundo son gratis!");

Dado que la línea contiene " mi”, el resultado de este código será .e.

Aplicar una expresión regular a una cadena

En Javascript, estas expresiones también se pueden utilizar con dos métodos del objeto String: buscar() y reemplazar(). Son necesarios para realizar búsquedas y reemplazos en texto.

  • método search(): utiliza una expresión para buscar una coincidencia y devuelve información sobre la ubicación de la coincidencia;
  • El método replace() devuelve una cadena modificada con un patrón reemplazado.

Ejemplos

Usar una expresión regular JS para realizar una búsqueda que distinga entre mayúsculas y minúsculas para la frase " w3escuelas" en línea:

var str = "Visita W3Schools"; var n = str.search(/w3schools/i);

El resultado en n será 6.

El método de búsqueda también toma una cadena como argumento. El argumento de cadena se convertirá en una expresión regular:

Usando una cadena para buscar la frase " W3escuelas" en línea:

var str = "¡Visite W3Schools!"; var n = str.search("W3Schools");

Usar una expresión regular JS que distinga entre mayúsculas y minúsculas para reemplazar " microsoft" en " W3Escuelas" en línea:

var str = "¡Visite Microsoft!"; var res = str.replace(/microsoft/i, "W3Schools");

Como resultado, obtendremos: “¡Visite W3Schools! ".

El método replace() también acepta una cadena de búsqueda:

var str = "¡Visite Microsoft!"; var res = str.replace(“Microsoft”, “W3Schools”);

Traducción del artículo “ Usando expresiones regulares en Javascript” fue preparado por el amigable equipo del proyecto

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

Si tienes un problema y vas a resolverlo 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 ) );

// Pasa todo 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.

El tema de las expresiones regulares es bastante extenso y no se puede cubrir en una sola lección, pero el propósito de nuestras lecciones es brindarle una comprensión básica del lenguaje JavaScript y sus capacidades, por lo que es imposible ignorar las expresiones regulares.

Primero, averigüemos qué es.
Expresión regular- esta es una instrucción que describe en un lenguaje especialmente desarrollado (RegExp) la ley de "similitud" de la cadena deseada con el patrón.

¿Para qué sirve? Por ejemplo:

  • Organizar una búsqueda de algo en el texto.
  • Reemplazar una parte de subcadenas por otras.
  • Para verificar la exactitud de la entrada del usuario (probablemente se haya encontrado con una situación más de una vez cuando ingresó su dirección de correo electrónico en algún formulario y recibió un error como "Correo electrónico no válido").

No entraremos en detalles, pero veamos cómo configurar expresiones regulares. Hay dos formas, en esta lección veremos una (creación en notación literal):

Var p=/patrón/banderas;

Dónde
patrón- un patrón es la base de una expresión regular que define criterios de coincidencia de cadenas. Consta de literales y metacaracteres.
banderas- banderas (modificadores), especificar Opciones adicionales la coincidencia de patrones.

Varpar=/+/i;

Aquí + - una plantilla que literalmente significa lo siguiente "cualquier número de números y letras 1 o más veces" (veremos cómo configurar una plantilla a continuación).

i

Para que quede más claro de qué estamos hablando, veamos un ejemplo. Supongamos que tenemos un formulario donde el usuario ingresa su correo electrónico y contraseña. Queremos que cuando haga clic en el botón "Registrarse", se verifique que la entrada sea correcta.

El código de la página HTML será el siguiente:

expresiones regulares javascript

Formulario de inscripción



Entonces, ¿qué debería hacer la función? dirección_prov()? Para comenzar necesitamos dos variables en las que colocaremos los valores ingresados ​​por el usuario:

función prov_adress(obj) ( var adr=obj.mail.value; var par=obj.pas.value; )

Ahora necesitamos establecer patrones (expresiones regulares) con los que compararemos lo que ingresó el usuario. Aquí solo los daré; hablaremos de cómo componerlos más adelante:

función prov_adress(obj) ( var adr=obj.mail.value; var par=obj.pas.value; var adr_pattern=/+@+\.(2,5)/i; var par_pattern=/+/i; )

Ahora comprobamos la coincidencia de patrones. Para ello utilizaremos el método prueba objeto ExpReg:

función prov_adress(obj) ( var adr=obj.mail.value; var par=obj.pas.value; var adr_pattern=/+@+\.(2,5)/i; var par_pattern=/+/i; var prov=adr_pattern.test(adr); var prov1=par_pattern.test(par);

Línea adr_pattern.prueba(adr) significa lo siguiente: verificar la existencia en una cadena dirección secuencia que coincide con la expresión regular patrón_adr. Método prueba devuelve un valor booleano (verdadero o falso).

Lo único que tenemos que hacer es indicar en nuestra función qué hacer en caso de una verificación exitosa (o fallida):

función prov_adress(obj) ( var adr=obj.mail.value; var par=obj.pas.value; var adr_pattern=/+@+\.(2,5)/i; var par_pattern=/+/i; var prov=adr_pattern.test(adr); var prov1=par_pattern.test(par); if (prov==true && prov1==true) ( ​​alerta("¡Estás registrado!"); ) else ( alerta(" Los datos ingresados ​​son incorrectos !"); ) )

Listo, espero que entiendas la esencia de lo que estamos haciendo. Pero antes de comprobar el funcionamiento de nuestro script, veamos en qué consisten nuestras expresiones regulares.

Tomemos una expresión regular para nuestra contraseña: /+/yo:

  • /+/ - una plantilla en la que:
    • 0-9 - cualquier número.

    • Arizona- cualquier letra minúscula de la a a la z.

    • - los corchetes significan que el patrón puede contener cualquiera de los literales enumerados en ellos (en nuestro caso, números y letras minúsculas)

    • + - indica que esta parte del patrón (es decir, lo que está entre corchetes) se puede repetir una o más veces.


  • i- una bandera que indica que las mayúsculas y minúsculas de los caracteres no importan.

En otras palabras, nuestra expresión regular especifica que la contraseña puede contener cualquier número de números y letras 1 o más veces (es decir, puede constar de un número, una letra, muchos números, muchas letras, números y letras).

Por ejemplo, si el usuario ingresa "2", "a3b" o "leopard" en el campo de contraseña, dicha contraseña se considerará correcta. Y si ingresa "ab&s" o "24?", dicha contraseña no se considerará correcta, porque contiene caracteres especiales y no los permitimos en la expresión regular.

Espero que ahora quede claro cómo y por qué se pueden utilizar expresiones regulares, solo queda aprender los principios de su composición. Estrictamente hablando, la tarea de componer una expresión regular se reduce a crear su plantilla. Y la plantilla, como recordarás, puede constar de literales y metacaracteres.

Comencemos con lo más simple: los literales:

  • Cada uno de estos símbolos se representa a sí mismo. Por ejemplo, /abc/: sólo la cadena "abc" coincide con este patrón.

  • Arizona- todas las letras minúsculas de la a a la z. Por ejemplo, /a-z/: este patrón coincide con 26 cadenas: "a", "b", "c"... "z"

  • ARIZONA- Todo letras mayúsculas de la A a la Z.

  • 0-9 - todos los números.

Si queremos indicar que puede haber varios números o letras, tendremos que utilizar caracteres de control:
  • * - indica que el carácter (o parte del patrón, si está entre corchetes) se puede repetir 0 o más veces. Por ejemplo, /ab*c/ - significa que la línea comienza con el carácter a, luego puede haber cualquier número de caracteres b, seguidos del carácter c. Aquellos. podrían ser, por ejemplo, las siguientes cadenas: "ac", "abc", "abbbbbbc", etc.

  • + - indica que el carácter (o parte del patrón, si está entre corchetes) se puede repetir 1 o más veces. Por ejemplo, /ab+c/ - significa que la línea comienza con el carácter a, luego puede haber cualquier número de caracteres b (pero no menos de 1), seguidos del carácter c. Aquellos. podrían ser, por ejemplo, las siguientes cadenas: "abc", "abbbbbbc", etc.

  • . - indica que este lugar puede contener cualquier carácter excepto un carácter de nueva línea. Por ejemplo, para el patrón /ab.c/ las siguientes cadenas son comparables: "ab6c", "abxc", "ab=c", etc.

  • ? - indica que el carácter (o parte del patrón, si está entre corchetes) se puede repetir 0 o 1 vez. Por ejemplo, /ab?c/ - significa que la línea comienza con el carácter a, luego puede haber o no un carácter b, seguido del carácter c. Aquellos. Estas podrían ser las siguientes cadenas: "ac", "abc"

  • (norte)- indica que el carácter (o parte del patrón, si está entre corchetes) se puede repetir exactamente n veces. Por ejemplo, /ab(3)c/ - significa que la línea comienza con el carácter a, luego hay 3 caracteres b, seguidos por el carácter c. Aquellos. esta será la cadena "abbbc".

  • (norte,)- indica que el carácter (o parte del patrón, si está entre corchetes) se puede repetir no más veces. Por ejemplo, /ab(3,)c/ - significa que la línea comienza con el carácter a, luego hay 3 o más caracteres b, seguidos por el carácter c. Aquellos. podrían ser las siguientes cadenas: "abbbc", "abbbbbbc", etc.

  • (norte, metro)- indica que el carácter (o parte del patrón, si está entre corchetes) se puede repetir n a m veces. Por ejemplo, /ab(1,3)c/ - significa que la línea comienza con el carácter a, luego hay de 1 a 3 caracteres b, seguidos por el carácter c. Aquellos. podrían ser las siguientes cadenas: "abc", "abbc", "abbc".

  • - tal patrón es comparable a cualquier carácter individual perteneciente al conjunto definido entre paréntesis. Un conjunto se especifica mediante una enumeración o especificando un rango. Por ejemplo, el patrón // puede coincidir con las siguientes cadenas: "a", "b", "c".

  • [^] - tal patrón es comparable a cualquier carácter que no pertenezca al conjunto definido entre paréntesis. Por ejemplo, el patrón /[^abc]/ puede coincidir con las cadenas: "f", "x", "Z", pero no puede coincidir con las cadenas: "a", "b", "c".

  • ^ - indica que los caracteres son comparables al comienzo de la línea. Por ejemplo, el patrón /^abc/ puede coincidir con las cadenas: "abcd", "abcfh", pero no puede coincidir con las cadenas: "dabc", "cbabc", etc.

  • $ - indica que los caracteres coinciden con el final de la línea. Por ejemplo, el patrón /abc$/ puede coincidir con las cadenas: "dabc", "fhabc", pero no puede coincidir con las cadenas: "abcd", "abccb", etc.

  • | - indica varios patrones alternativos. Por ejemplo, el patrón /ab|c/ coincidirá con las siguientes cadenas: "ab" y "c".

  • \ - sirve para escapar de caracteres especiales, es decir. una barra invertida antes de un carácter indica que debe interpretarse como especial. Por ejemplo:
    • \d- coincide con cualquier número del 0 al 9.

    • \D- todo coincide excepto el número.

    • \s- corresponde a un espacio.

    • \S- coincide con todo excepto un espacio.

    • \w- coincide con una letra, número o guión bajo.

    • \W- coincide con todo excepto una letra, un número o un guión bajo.


  • Por ejemplo, el patrón /x\d\d/ coincidirá con las cadenas: "x01", "x25", etc., pero no coincidirá con las cadenas: "A15", "x0A"...

    La barra invertida también se utiliza para convertir un carácter especial en literal. Por ejemplo, si necesitamos encontrar la cadena "a*b", especificaremos el siguiente patrón /a\*b/.

Usando los literales y metacaracteres anteriores, puede crear cualquier patrón que desee (piense en expresiones regulares). Veamos, por ejemplo, lo que escribimos para la plantilla de correo electrónico en nuestro ejemplo:

Var adr_pattern=/+@+\.(2,5)/i;

Entonces, especificamos que la dirección de correo electrónico tiene números, letras y guiones bajos 1 o más veces, seguidos de @, luego números, letras y guiones bajos nuevamente 1 o más veces, luego un punto seguido de letras de 2 a 5 veces. Así es aproximadamente como se ven las direcciones de correo electrónico.

Ahora, sabiendo exactamente qué especificamos en el ejemplo, puede verificar el funcionamiento del ejemplo:

Algunas personas, cuando se enfrentan a un problema, piensan: "Oh, usaré expresiones regulares". Ahora ellos 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 una herramienta de este tipo: las expresiones regulares. Esta es una forma de describir patrones en datos de cadena. 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 esto herramienta poderosa para explorar y procesar cadenas. 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. En primer lugar, dado que el patrón termina con una barra diagonal, debes poner 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 encontrar 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 aún 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 el rango de caracteres donde se especifica la secuencia. 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 punto. 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 el grupo completo(hoo+), encontrando una o más de estas 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 habituales 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 propiedad de índice, que contiene el número del carácter del que 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 cuyo paréntesis apareció 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 tipo estándar Objeto para fechas, o mejor dicho, momentos en el tiempo. Se llama Fecha. Si simplemente crea un objeto de fecha a través de nuevo, obtendrá fecha actual y tiempo.

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 desde la 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, lo que significa que una coincidencia sólo se produce si se cumple una determinada condición.

Plantillas con elección

Digamos que necesita saber 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.

Buscador

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 una coincidencia de nuestro carácter habitual en 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 rectángulo límite de la última 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 a 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 los datos de entrada varias veces. diferentes caminos. Por ejemplo, si cometemos un error al escribir una expresión regular para numeros 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 la 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á a 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); si no (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 de 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 expresión 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 regexp = 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 funciona. manera conveniente comience a buscar 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, en 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 múltiples llamadas ejecutivas, estas actualizaciones automáticas lastIndex puede causar problemas. Su servidor habitual puede comenzar a buscar desde la posición izquierda 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 recorrer 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."; var número = /\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. modo automatico. (No escribiremos el programa completo, solo la parte que lee el archivo de configuración. Lo siento.) 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.
- comienzan las líneas entre corchetes 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 tanto \n como \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 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", los usuarios habituales de JavaScript son estúpidos con caracteres que no se encuentran en idioma en 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 "todos letras mayúsculas", "todos los signos de puntuación" o "caracteres de control". Hay planes para agregar dichas categorías a JavaScript, pero probablemente no se implementarán pronto.

Línea de fondo

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 saltos de línea
/\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 que devuelve solo la posición inicial de la aparición. 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 llenarlas con una tarea para la que no están destinadas.

Ejercicios

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 necesitas expresarte programa dado 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

// Ingrese sus 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 en todas partes solías indicar diálogos. comillas simples. 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 los 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, .5 o 5. – 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 + """); ));




Arriba