Búsqueda de expresiones regulares sin incluir una cadena. Javascript, expresión regular: ejemplos, comprobación de expresiones regulares. Grupos y rangos

nueva RegExp(patrón[, banderas])

expresión regular AVANZAR

Se sabe que se prefiere la sintaxis literal(/prueba/i).

Si la expresión regular no se conoce de antemano, es preferible crear una expresión regular (en una cadena de caracteres) utilizando el constructor (nueva RegExp).

Pero preste atención, dado que el “signo de barra diagonal” \ desempeña el papel de cambio de código, debe escribirse dos veces en la cadena literal (nueva RegExp): \\

Banderas

ignoro mayúsculas y minúsculas al hacer coincidir

g la coincidencia global, a diferencia de la coincidencia local (de forma predeterminada, coincide solo con la primera instancia del patrón), permite coincidencias de todas las instancias del patrón.

Operadores

Qué Cómo Descripción Uso
i bandera hace reg. expresión que no distingue entre mayúsculas y minúsculas /testik/i
gramo bandera búsqueda global /testik/g
metro bandera permite comparar muchas cadenas que se pueden obtener del área de texto
operador de clase de carácter coincidencia de juego de caracteres - cualquier carácter en el rango de la a a la z;
^ operador de intercalación excepto [^a-z] - cualquier carácter EXCEPTO los caracteres en el rango de la a a la z;
- operador de guión indicar el rango de valores, inclusive - cualquier carácter en el rango de la a a la z;
\ operador de escape escapa de cualquier carácter siguiente \\
^ comenzar a emparejar operador La coincidencia de patrones debe ocurrir al principio. /^testik/g
$ operador de fin de coincidencia La coincidencia de patrones debe ocurrir al final. /testik$/g
? ¿operador? hace que el personaje sea opcional /t?est/g
+ operador + /t+est/g
+ operador + el símbolo debe estar presente una o varias veces /t+est/g
* operador * el símbolo debe estar presente una o varias veces o estar ausente por completo /t+est/g
{} operador() establecer un número fijo de repeticiones de caracteres /t(4)est/g
{,} operador (,) establecer el número de repeticiones de un símbolo dentro de ciertos límites /t(4,9)est/g

Clases de caracteres predefinidas

Miembro predefinido Comparación
\ t pestaña horizontal
\norte avance de línea
. Cualquier carácter excepto avance de línea
\d Cualquier décimo dígito, que es equivalente
\D Cualquier carácter distinto del décimo dígito, que equivale a [^0-9]
\w Cualquier carácter (números, letras y guiones bajos) que sea equivalente
\W Cualquier carácter que no sean números, letras y guiones bajos, que equivale a [^A-Za-z0-9]
\s Cualquier carácter de espacio
\S Cualquier carácter excepto el espacio.
\b Límite de palabra
\B NO el límite de la palabra, sino su interior. Parte

Agrupamiento()

Si desea aplicar un operador como + (/(abcd)+/) a un grupo de miembros, puede utilizar paréntesis () .

Fijaciones

La parte de la expresión regular encerrada entre paréntesis () se llama fijación.

Considere el siguiente ejemplo:

/^()k\1/

\1 no es ningún carácter de a , b , c .
\1 es cualquier carácter que inicia coincide con el primer carácter. Es decir, el carácter que coincide con \1 se desconoce hasta que se resuelve la expresión regular.

Grupos no fijados

Los corchetes () se utilizan en 2 casos: para agrupar y para indicar fijaciones. Pero hay situaciones en las que necesitamos usar () solo para agrupar, ya que no se requieren confirmaciones; además, al eliminar confirmaciones innecesarias, facilitamos el mecanismo de procesamiento de expresiones regulares.

Así que prevenir la fijación Antes del paréntesis de apertura debes poner: ?:

cadena = "

Hola ¡mundo!
"; encontrado = str.match(/<(?:\/?)(?:\w+)(?:[^>]*?)>/i); console.log("encontrado sin solución: ", encontrado); // [ "
" ]

función de prueba

expresión regular.prueba()

La función de prueba comprueba si la expresión regular coincide con la cadena (cadena). Devuelve verdadero o falso.

Ejemplo de uso:

JavaScript

función códigoF(str)( return /^\d(5)-\d(2)/.test(str); ) //console.log(codeF("12345-12ss")); // verdadero //console.log(codeF("1245-12ss")); // FALSO

función de coincidencia

str.match(expresación regular)

La función de coincidencia devuelve una matriz de valores o nulo si no se encuentran coincidencias. Controlar: si la expresión regular no tiene la bandera g (para realizar una búsqueda global), entonces el método de coincidencia devolverá la primera coincidencia en la cadena y, como se puede ver en el ejemplo, en una matriz de coincidencias. FIJACIONES caen(parte de la expresión regular entre paréntesis).

JavaScript

str = "Para obtener información, consulte: Capítulo 3.4.5.1"; re = /chapter (\d+(\.\d)*)/i // con confirmaciones (sin indicador global) encontrado = str.match(re) console.log(found); // ["Capítulo 3.4.5.1", "3.4.5.1", ".1"]

Si proporciona al método match() una expresión regular global (con la bandera g), también se devolverá una matriz, pero con partidos GLOBALES. Es decir, los resultados registrados no se devuelven.

JavaScript

str = "Para obtener información, consulte: Capítulo 3.4.5.1, Capítulo 7.5"; re = /chapter (\d+(\.\d)*)/ig // sin confirmaciones - encontrado globalmente = str.match(re) console.log(found); // ["Capítulo 3.4.5.1", "Capítulo 7.5"]

función ejecutiva

regexp.exec(cadena)

La función ejecutiva comprueba si una expresión regular coincide con una cadena (cadena). Devuelve una matriz de resultados (con confirmaciones) o nulo. Cada llamada posterior a exec (por ejemplo, cuando se usa while) ocurre (al ejecutar exec actualiza automáticamente el índice del final de la última búsqueda, lastIndex) y pasa a la siguiente coincidencia global (si se especifica el indicador g).

JavaScript

varhtml = "
¡BAM! ¡CULO!
"; varreg=/<(\/?)(\w+)([^>]*?)>/g; //console.log(reg.exec(html)); // ["
", "", "div", " class="test""] while((match = reg.exec(html)) !== null)( console.log(reg.exec(html)); ) /* [" ", "", "b", ""] [" ", "", "ellos", ""] ["
", "/", "div", ""] */

Sin la bandera global, los métodos match y exec funcionan de manera idéntica. Es decir, devuelven una matriz con la primera coincidencia global y confirmaciones.

JavaScript

// coincide con var html = "
¡BAM! ¡CULO!
"; varreg=/<(\/?)(\w+)([^>]*?)>/; // sin consola global.log(html.match(reg)); // ["
", "", "div", " class="test""] // exec var html = "
¡BAM! ¡CULO!
"; varreg=/<(\/?)(\w+)([^>]*?)>/; // sin consola global.log(reg.exec(html)); // ["
", "", "div", " class="prueba""]

reemplazar la función

str.replace(expresación regular, newSubStr|función)
  • expresión regular - reg. expresión;
  • newSubStr: la cadena a la que se cambia la expresión encontrada en el texto;
  • función: se llama para cada coincidencia encontrada con una lista variable de parámetros (recuerde que una búsqueda global en una cadena encuentra todas las instancias de una coincidencia de patrón).

El valor de retorno de esta función sirve como reemplazo.

Parámetros de función:

  • 1 - Subcadena coincidente completa.
  • 2 - El significado de los grupos de brackets (fijaciones).
  • 3 - Índice (posición) de la coincidencia en la cadena fuente.
  • 4 - Cadena fuente.

El método no cambia la cadena de llamada, pero devuelve una nueva después de reemplazar las coincidencias. Para realizar una búsqueda y reemplazo global, use expresiones regulares con el indicador g.

"GHGHGHGTTTT".replace(//g,"K"); //"KKKKKKKKKKKK"

JavaScript

función upLetter(allStr,letter) ( return letter.toUpperCase(); ) var res = "border-top-width".replace(/-(\w)/g, upLetter); consola.log(res); //borderAnchoSuperior

Expresiones regulares para principiantes.

¿Qué son las expresiones regulares?

Si alguna vez trabajó con la línea de comando, probablemente haya usado máscaras de nombre de archivo. Por ejemplo, para eliminar todos los archivos del directorio actual que comiencen con la letra "d", podría escribir rm d* .

Las expresiones regulares son una herramienta similar, pero mucho más poderosa, para encontrar cadenas, probarlas con un patrón y realizar otros trabajos similares. El nombre en inglés de este instrumento es Expresiones regulares o simplemente ExpReg. Estrictamente hablando, las expresiones regulares son un lenguaje especial para describir patrones de cadenas.

La implementación de esta herramienta varía en los diferentes lenguajes de programación, aunque no mucho. En este artículo nos centraremos principalmente en la implementación de expresiones regulares compatibles con Perl.

Conceptos básicos de sintaxis

En primer lugar, cabe señalar que cualquier cadena en sí misma es una expresión regular. Entonces, la expresión Jaja, obviamente, corresponderá a la línea “Jaja” y sólo eso. Las expresiones regulares distinguen entre mayúsculas y minúsculas, por lo que la cadena "jaja" (minúscula) ya no coincidirá con la expresión anterior.

Sin embargo, aquí hay que tener cuidado: como en cualquier lenguaje, las expresiones regulares tienen caracteres especiales a los que se les debe aplicar escape. Aquí está su lista: . ^$*+? ( ) \ | (). El escape se realiza de la forma habitual: agregando \ antes del carácter especial.

conjunto de caracteres

Supongamos que queremos encontrar todas las interjecciones en un texto que indiquen risa. Jaja simplemente no nos conviene; después de todo, "Jeje", "Hoho" y "Hihi" no se incluirán. Y el problema con el caso de la primera letra debe resolverse de alguna manera.

Aquí los conjuntos vendrán en nuestra ayuda: en lugar de especificar un carácter específico, podemos escribir una lista completa, y si alguno de los caracteres enumerados aparece en el lugar especificado en la cadena que se está examinando, la cadena se considerará adecuada. Los patrones están escritos entre corchetes; el patrón coincidirá con cualquiera de los caracteres "a", "b", "c" o "d".

Conjunto interior b oh No es necesario utilizar caracteres de escape para la mayoría de los caracteres especiales, pero usar \ delante de ellos no se considerará un error. Aún es necesario escapar los caracteres “\” y “^”, y, preferiblemente, “]” (por lo tanto, significa cualquiera de los caracteres “]” o “[”, mientras que [x] es exclusivamente la secuencia “[ incógnita]"). El comportamiento aparentemente inusual de las expresiones regulares con el carácter "]" en realidad está determinado por reglas bien conocidas, pero es mucho más fácil simplemente escapar de este carácter que recordarlas. Además, el símbolo “-” debe tener carácter de escape; se utiliza para establecer rangos (ver más abajo).

Si escribe el símbolo ^ inmediatamente después de [, el conjunto adquirirá el significado opuesto: cualquier símbolo distinto de los especificados se considerará adecuado. Entonces, el patrón [^xyz] coincide con cualquier carácter excepto, de hecho, “x”, “y” o “z”.

Entonces, aplicando esta herramienta a nuestro caso, si escribimos [Xx][aoie]x[aoie], entonces cada una de las cadenas “Jaja”, “jeje”, “hihi” e incluso “Hoho” coincidirán con el patrón.

Clases de caracteres predefinidas

Para algunos conjuntos que se utilizan con bastante frecuencia, existen plantillas especiales. Entonces, para describir cualquier carácter de espacio en blanco (espacio, tabulación, salto de línea) se usa \s, para números - \d, para caracteres latinos, números y guiones bajos "_" - \w.

Si es necesario describir algún carácter, se utiliza un punto para ello. . Si las clases especificadas se escriben con una letra mayúscula (\S, \D, \W), cambiarán su significado al contrario: cualquier carácter que no sea un espacio en blanco, cualquier carácter que no sea un número y cualquier carácter que no sea el Alfabeto latino, números o guión bajo, respectivamente.

Además, utilizando expresiones regulares, es posible comprobar la posición de una línea con respecto al resto del texto. La expresión \b denota un límite de palabra, \B es un límite que no es de palabra, ^ es el comienzo del texto y $ es el final. Entonces, según el patrón \bJava\b, los primeros 4 caracteres se encontrarán en la línea "Java y JavaScript", y según el patrón \bJava\B, los caracteres del 10 al 13 (como parte de la palabra " JavaScript”).

Rangos

Es posible que deba designar un conjunto que contenga letras, por ejemplo, de la “b” a la “f”. En lugar de escribir [bvgdezziklmnoprstuf] puedes usar el mecanismo de rango y escribir [b-f] . Así, el patrón x corresponde a la cadena “xA6”, pero no corresponde a “xb9” (en primer lugar, debido a que en el rango solo se indican letras mayúsculas, y en segundo lugar, debido a que 9 no está incluido en el intervalo 0 -8).

El mecanismo de rango es especialmente relevante para el idioma ruso, porque para él no existe una construcción similar a \w . Para designar todas las letras del alfabeto ruso, puede utilizar el patrón [а-яА-ЯеО] . Tenga en cuenta que la letra "е" no está incluida en el rango general de letras y debe especificarse por separado.

Cuantificadores (que indican el número de repeticiones)

Volvamos a nuestro ejemplo. ¿Qué pasaría si una interjección de “risa” tuviera más de una vocal entre las x, como “Haahaaaa”? Nuestra antigua temporada regular ya no podrá ayudarnos. Aquí tendremos que utilizar cuantificadores.

Tenga en cuenta que el cuantificador solo se aplica al carácter que le precede.

Algunas construcciones de uso frecuente han recibido notaciones especiales en el lenguaje de expresiones regulares:

Entonces, con la ayuda de cuantificadores, podemos mejorar nuestro patrón para interjecciones a [Xx][aoeee]+x[aoeee]*, y será capaz de reconocer las cadenas “Haaha”, “heeeeeeh” y “Heehee”.

Cuantificación perezosa

Supongamos que nos enfrentamos a la tarea de encontrar todas las etiquetas HTML en una cadena.

Proger- mi Querida sitio web sobre programación!

La solución obvia<.*>no funcionará aquí: encontrará la cadena completa, porque comienza y termina con una etiqueta de párrafo. Es decir, se considerará que el contenido de la etiqueta es la cadena

P> Proger- mi Querida sitio web sobre programación!

Esto sucede debido al hecho de que, de forma predeterminada, el cuantificador funciona según el llamado. avaro algoritmo: intenta devolver la cadena más larga posible que coincida con la condición. Hay dos formas de resolver el problema. La primera es utilizar la expresión.<[^>]*> , lo que evitará que el corchete angular sea considerado como contenido de la etiqueta. La segunda es declarar que el cuantificador no es codicioso, sino perezoso. ¿Esto se hace agregando a la derecha del cuantificador de caracteres? . Aquellos. para buscar todas las etiquetas, la expresión cambiará a<.*?> .

Cuantificación celosa

A veces, para aumentar la velocidad de búsqueda (especialmente en los casos en que la cadena no coincide con la expresión regular), puede evitar que el algoritmo regrese a los pasos de búsqueda anteriores para encontrar posibles coincidencias para el resto de la expresión regular. se llama celoso cuantificación. El cuantificador se pone celoso añadiendo un símbolo + a la derecha. Otro uso de la cuantificación de los celos es excluir coincidencias no deseadas. Por lo tanto, el patrón ab*+a en la cadena “ababa” coincidirá sólo con los primeros tres caracteres, pero no con los caracteres del tercero al quinto, porque el carácter “a”, que está en la tercera posición, ya se ha utilizado para el primer resultado.

Grupos de corchetes

Para nuestro modelo de interjección “de risa”, lo único que nos queda es tener en cuenta que la letra “x” puede aparecer más de una vez, por ejemplo, “Hahahahahaaahahooo”, e incluso puede terminar con la letra “x”. Probablemente necesitemos usar un cuantificador de grupo [aioe]+x aquí, pero si simplemente escribimos [aoie]x+ el cuantificador + solo se aplicará al carácter “x” y no a toda la expresión. Para solucionar este problema, se debe colocar la expresión entre paréntesis: ([aioe]x)+ .

Por lo tanto, nuestra expresión se convierte en [Хх]([аое]х?)+ - primero hay una “x” mayúscula o minúscula, y luego un número arbitrario distinto de cero de vocales, que (posiblemente, pero no necesariamente) están intercaladas con una sola “x” minúscula. Sin embargo, esta expresión resuelve el problema sólo parcialmente; esta expresión también incluirá líneas como, por ejemplo, “hihaheh”; alguien puede reírse así, pero la suposición es muy dudosa. Obviamente, sólo podemos usar un conjunto de todas las vocales una vez, y luego debemos confiar de alguna manera en el resultado de la primera búsqueda. ¿Pero cómo?...

Recordar el resultado de la búsqueda por grupo (comentarios)

Resulta que el resultado de una búsqueda de un grupo de corchetes se escribe en una celda de memoria separada, a la que se puede acceder para usarlo en partes posteriores de la expresión regular. Volviendo a la tarea de encontrar etiquetas HTML en una página, es posible que necesitemos no solo encontrar las etiquetas, sino también averiguar su nombre. Una expresión regular puede ayudarnos con esto.<(.*?)> .

Proger- mi Querida sitio web sobre programación!

Resultado de la búsqueda para todas las expresiones regulares: “

”, “”, “”, “”, “”, “

”.
Resultado de la búsqueda para el primer grupo: “p”, “b”, “/b”, “i”, “/i”, “/i”, “/p”.

Se puede hacer referencia al resultado de la búsqueda por grupo usando la expresión \n, donde n es un número del 1 al 9. Por ejemplo, la expresión (\w)(\w)\1\2 coincide con las cadenas “aaaa”, “abab ”, pero no coincide con “aabb”.

Si una expresión se coloca entre paréntesis solo para aplicarle un cuantificador (no hay planes para recordar el resultado de la búsqueda para este grupo), inmediatamente se debe agregar el primer paréntesis?:, por ejemplo (?:+\w) .

Usando este mecanismo, podemos reescribir nuestra expresión en la forma [Xx]([aoie])x?(?:\1x?)* .

Transferir

Para comprobar si una cadena satisface al menos uno de los patrones, puede utilizar un análogo del operador booleano O, que se escribe con el símbolo | . Por lo tanto, el patrón Anna|Soledad incluye las líneas “Anna” y “Soledad”, respectivamente. Es especialmente conveniente utilizar enumeraciones dentro de grupos entre corchetes. Entonces, por ejemplo, (?:a|b|c|d) es completamente equivalente (en este caso, la segunda opción es preferible debido al rendimiento y la legibilidad).

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

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

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

Opciones de búsqueda

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

Caracteres en expresiones regulares de JavaScript

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

Trabajar con expresiones regulares en Javascript

El trabajo con expresiones regulares en Javascript se implementa utilizando métodos de la clase String.

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

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

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

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

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

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

Caracteres especiales en la cadena de reemplazo

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

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

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

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

En este capítulo, analizaremos dicha herramienta: las expresiones regulares. Esta es una forma de describir patrones en datos de 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 es una herramienta poderosa para explorar y manipular cuerdas. Una vez que los comprenda, se convertirá en un programador más eficaz.

Creando una expresión regular

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

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

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

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

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

Var dieciochoMás = /dieciocho\+/;

Para saber qué caracteres deben ir precedidos por una barra, 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 un rango de caracteres, donde la secuencia se especifica mediante la codificación Unicode. Los caracteres del 0 al 9 están en una fila (códigos del 48 al 57), por lo que los captura a todos y coincide con cualquier número.

Varios grupos de caracteres tienen sus propias abreviaturas integradas.

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

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

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

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

Las barras invertidas también se pueden utilizar entre corchetes. Por ejemplo, [\d.] significa cualquier número o 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 todo el grupo (hoo+), encontrando una o más de esas secuencias.

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

Partidos y grupos

El método de prueba es el método más sencillo para comprobar expresiones regulares. Sólo le indica si se encontró una coincidencia o no. Los 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 una propiedad de índice, que contiene el número del carácter a partir del cual se produjo la coincidencia. En general, el objeto parece una matriz de cadenas, donde el primer elemento es la cadena cuya coincidencia se comprobó. En nuestro ejemplo, esta será la secuencia de números que estábamos buscando.

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

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

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

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

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

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

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

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

Tipo de fecha

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

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

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

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

JavaScript utiliza una convención en la que los números de mes comienzan con cero y los números de día comienzan con uno. Esto es estúpido y ridículo. 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 que significa que una coincidencia sólo ocurre si se cumple una determinada condición.

Plantillas con elección

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

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

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

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

motor de búsqueda

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

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

Esto significa que verificar 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 cuarta 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 una b, un número decimal sin sufijo o un número hexadecimal (los números del 0 al 9 o los símbolos de la a a la h), seguidos de h. Diagrama relevante:

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

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

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

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

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

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

método de reemplazo

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

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

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

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

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

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

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

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

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

Ejemplo sencillo:

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

Aquí hay uno más interesante:

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

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

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

Codicia

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

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

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

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

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

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

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

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

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

Crear dinámicamente objetos RegExp

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

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

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

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

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

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

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

método de búsqueda

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

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

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

propiedad último índice

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

Un objeto regex tiene propiedades. Uno de ellos es la fuente, que contiene una cadena. Otro es lastIndex, que controla, 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 varias llamadas ejecutivas, estas actualizaciones automáticas de lastIndex pueden 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 iterar a través de todas las apariciones de un patrón en una cadena para que pueda acceder al objeto coincidente en el cuerpo del bucle usando lastIndex y exec.

Var input = "Una línea con 3 números... 42 y 88."; 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 de forma automática. (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 vacías y las líneas que comienzan con punto y coma.
- las líneas entre corchetes comienzan una nueva sección
- líneas que contienen un identificador alfanumérico seguido de = agregar una configuración en esta sección

Todo lo demás son datos incorrectos.

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

Dado que el archivo debe analizarse línea por línea, es una buena idea comenzar dividiendo el archivo en líneas. Para hacer esto, usamos string.split("\n") en el Capítulo 6. Algunos sistemas operativos no utilizan un carácter \n para los saltos de línea, sino dos: \r\n. Dado que el método de división toma expresiones regulares como argumento, podemos dividir líneas usando la expresión /\r?\n/, permitiendo 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 una configuración normal, en cuyo caso se agrega al objeto actual.

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

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

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

Símbolos internacionales

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

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

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

En pocas palabras

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

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

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

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

Los caracteres normales tienen configuraciones que se escriben después de la barra diagonal 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.

Ceremonias

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

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

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

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

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

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

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

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

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

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: usar un literal de expresión regular 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.

No es necesario colocar expresiones regulares 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 la 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 la fila.

Elección