Puntos de conocimiento de expresiones regulares que vale la pena recopilar en la interfaz para la alfabetización

Muchos principiantes en front-end se sienten intimidados cuando se encuentran con expresiones regulares. Cuando comencé a aprender, básicamente me salté el capítulo sobre expresiones regulares. Excepto por copiar algunas expresiones regulares de uso común en Internet para la verificación de formularios, el resto del tiempo casi Nunca entendí cómo escribir una expresión regular.

Sin embargo, cuando realmente quise escribir una expresión regular adecuada para un negocio específico, descubrí que mi conocimiento de las expresiones regulares era realmente limitado. Así que aquí también utilicé un mapa mental para clasificar algunos puntos de conocimiento que debes conocer sobre las expresiones regulares.

¿Qué es una expresión regular?

Expresiones regulares, también conocidas como expresiones regulares. (Inglés: expresión regular, a menudo abreviada como expresión regular, expresión regular o RE en código), un concepto en informática. Las expresiones regulares se utilizan a menudo para recuperar y reemplazar texto que coincide con un determinado patrón (regla).

En el proceso de desarrollo de software, estamos más o menos expuestos a expresiones regulares. Para el front-end, las expresiones regulares no solo pueden verificar formularios, buscar y reemplazar texto, sino que también pueden usarse como analizadores de sintaxis, AST y editores. y otros campos.

expresión regular

representación directa

Las cantidades directas también se llaman literales y se escriben de la siguiente manera:

/^\d+$/g

Las expresiones regulares escritas en formato directo se convertirán en un nuevo RegExpobjeto cuando se ejecuten. Creo que es porque las variables directas no tienen la capacidad de llamar a métodos, solo cuando se convierten en objetos es posible llamar a métodos. Es por eso /^\d+$/.test().

Cuando utilice un objeto regular en un bucle lastIndexpara determinar la condición de terminación, asegúrese de no utilizar la escritura de expresiones regulares literales, de lo contrario, cada bucle lastIndexse restablecerá a 0Esto se debe a que cada vez que se ejecuta una expresión regular literal, se convertirá en una Por supuesto, los nuevos objetos se convertirán en RegExpcorrespondientes .lastIndex0

Notación de objetos RegExp

var pattern = new RegExp(/^\d+$/, 'g')

El primer parámetro puede aceptar una expresión regular literal o una cadena. Al pasar una cadena como primer parámetro, no es necesaria una barra al principio o al final. Si se utiliza un carácter especial en la cadena, \debe ir \precedido uno. \, para evitar \que se escape en la cadena.

"\s" === "s" // true

Las cadenas "\\s"se pueden representar correctamente.\s

El segundo parámetro representa la bandera flags. Las banderas aceptables son i, g, metc.

banderas banderas

i

Si la bandera está habilitada i, las expresiones regulares se ejecutan sin distinguir entre mayúsculas y minúsculas.

/abc/i.test('abc')等价于/abc/i.test('ABC')

gramo

Si la bandera está habilitada g, la expresión regular realizará una coincidencia global y no dejará de coincidir inmediatamente después de hacer coincidir un resultado hasta que no haya caracteres posteriores que coincidan con las reglas de coincidencia.

metro

Si la bandera está habilitada m, la expresión regular realiza una coincidencia de varias líneas, que ^puede coincidir con el comienzo de cada línea o el comienzo de toda la cadena, y $puede coincidir con el final de cada línea o el final de toda la cadena.

/^\d+$/.test('123\n456') // false /^\d+$/m.test('123\n456') // true

Todavía puede coincidir con toda la cadena

/^\d+\n\d+$/m.test('123\n45') // true

calificador de posición

^

Coincide con el comienzo del personaje. Por ejemplo, si debe comenzar con un número, puedes escribir:

/^\d/

ps

El final del personaje coincidente. Por ejemplo, si debe terminar en un número, puedes escribir:

/\d$/

coincidencia de rango

[]La coincidencia de rango se implementa mediante corchetes .

Los corchetes []se utilizan para la coincidencia de rangos, que consiste en encontrar caracteres dentro de un rango determinado. Por ejemplo, [0-9]significa hacer coincidir números, pero [a-z]puede hacer coincidir cualquiera de los 26 caracteres desde las letras minúsculas de la a a la z.

Si desea hacer coincidir caracteres que no están entre corchetes, puede comenzar con entre corchetes ^, por ejemplo [^0-9], para hacer coincidir caracteres que no sean dígitos, lo que equivale a \D.

metacaracteres primarios

.

Coincide con \ncualquier carácter, excepto los de nueva línea. Si desea hacer coincidir cualquier carácter, debe utilizar /[.\n]*/.

\s

Coincide con cualquier carácter vacío, incluidos espacios, tabulaciones \t, tabulaciones verticales \v, avances de línea \n, retornos de carro \ry avances de formulario \f. \sEquivalente a [ \t\v\n\r\f], tenga en cuenta que hay un espacio en la primera posición entre corchetes.

Aquí también hablamos de la diferencia entre caracteres de avance de línea y retorno de carro:

  • Salto de línea \n: mueve el cursor hacia abajo una línea sin regresar al principio de la línea.
  • Carácter de retorno de carro \r: el cursor regresa al principio de la línea sin una nueva línea.

\S

\S\s, el conjunto inverso de y usando la relación inversa mutua de y, podemos hacer coincidir cualquier carácter, escrito de la siguiente manera \s:\S

/[\s\S]/

\d

\dSe utiliza para unir números, equivalente a [0-9].

\D

\D\d, el conjunto inverso, es decir, hacer coincidir no números, es equivalente a [^0-9].

\w

\wSe utiliza para hacer coincidir caracteres de palabras, incluidos , 0-9y guión bajo , equivalente a .a-zA-z_[A-Za-z0-9_]

\W

\WEs \wel conjunto inverso, utilizado para hacer coincidir caracteres que no son palabras, equivalente a [^A-Za-z0-9_].

\norte

\nEs un carácter de salto de línea que se encuentra a menudo en el desarrollo y \sse incluyen los mencionados anteriormente \n. Por lo tanto, \nlos caracteres que pueden coincidir también deben \scoincidir.

\b

\bSe utiliza para hacer coincidir los límites de las palabras, es decir, el principio o el final de una palabra.

De hecho, al principio no entendí muy bien \bsu papel en las expresiones regulares .

Hasta que probé este caso yo mismo

 
 

Copiar código

'I love you'.match(/love/) 'Iloveyou'.match(/love/)

Ambas expresiones pueden coincidir con el resultado "love".

Pero a veces no queremos que dicha cadena 'Iloveyou'coincida porque no tiene espacios entre palabras.

Entonces \btiene el significado de existencia. Mira el siguiente ejemplo:

 
 

Copiar código

'I love you'.match(/\blove\b/) 'Iloveyou'.match(/\blove\b/) // null

La primera expresión aún puede coincidir con el resultado normalmente, pero la segunda expresión no puede coincidir con el resultado, lo cual está en línea con nuestras expectativas.

Algunas personas pueden decir, entonces puedo usar espacios para hacer coincidir.

 
 

Copiar código

'I love you'.match(/ love /)

Los espacios \baún son un poco diferentes en este escenario, lo que se refleja matchen los resultados.

Si usa espacios para hacer coincidir, entonces matchel primer elemento en la matriz de resultados " love "tiene espacios, sin embargo, muchas veces no queremos obtener espacios en los resultados, por lo que \bel significado de existencia es más obvio.

\B

Lo \bcontrario, representa un límite sin palabras. En otras palabras, \Bcuando se utiliza la coincidencia, no puede haber espacios antes o después del carácter de destino.

Supongamos \Bprimero, por ejemplo

/\Babc/.test('111 abc') // false

Supongamos \Bmás tarde, por ejemplo.

/abc\B/.test('abc 111') // false

Personaje de escape\

Dado que muchos caracteres en las expresiones regulares tienen significados especiales, como,,,,,, si realmente desea que coincidan, debe agregar caracteres (de )escape .\[]+\

/\//.test('/'); // true

o |

La lógica de implementar OR es relativamente simple y está proporcionada por expresiones regulares |.

Cabe señalar que |lo que se separa es la subexpresión completa a su izquierda y derecha, no un solo carácter ordinario.

entonces,

/^ab|cd|ef$/.test('ab') // true 
/^ab|cd|ef$/.test('cd') // true 
/^ab|cd|ef$/.test('ace') // false

También tenga en cuenta que |hay una prioridad de izquierda a derecha, por lo que si el de la izquierda coincide, el de la derecha se ignora, incluso si la coincidencia de la derecha parece más "perfecta".

/a|ab/.exec('ab')得到的结果是

["a", index: 0, input: "ab", groups: undefined]

cuantificador

?

Coincide con la subexpresión anterior cero o una vez

+

Coincide con la subexpresión anterior una o más veces

*

Coincide con la subexpresión anterior cero o cualquier momento

{Nuevo Méjico}

Coincide con el carácter ordinario o subexpresión anterior al menos n veces y como máximo m veces

{norte,}

Coincide con el carácter ordinario o subexpresión anterior al menos n veces

{norte}

Coincide con el carácter ordinario o subexpresión anterior n veces

avaro

La coincidencia codiciosa consiste en hacer coincidir tanto como sea posible. Si se pueden cumplir las condiciones de coincidencia, ocupará las reglas de coincidencia posteriores tanto como sea posible.

La coincidencia codiciosa es la opción predeterminada, como /\d?/hacer coincidir 1tantos números como sea posible /\d+/y /\d*/hacer coincidir tantos números como sea posible.

Por ejemplo,

'123456789'.match(/^(\d+)(\d{2,})$/)

En el resultado anterior, el primer elemento del grupo de captura es "1234567"y el segundo elemento es "89".

¿Por qué esto es tan? Debido a \d+que es una coincidencia codiciosa, combine tantas como sea posible. Si no hay una posterior \d{2,}, el primer elemento en el grupo de captura será directamente "123456789". Pero debido a \d{2,}la existencia de, \d+salvará \d{2,}las apariencias y cumplirá con sus condiciones mínimas, es decir, acertará 2 números y \d+acertará 7 números por sí solo.

No codicioso

La coincidencia no codiciosa consiste en coincidir lo menos posible, generalmente agregando uno después del cuantificador ?, para indicar la menor coincidencia posible, dejando la oportunidad para las reglas de coincidencia posteriores +.*?

Tomemos el ejemplo en modo codicioso y cambiémoslo ligeramente \d+al modo no codicioso \d+?.

'123456789'.match(/^(\d+?)(\d{2,})$/)

El primer elemento del grupo de captura es "1"y el segundo se convierte en "23456789".

¿Por qué esto es tan? Porque en el modo no codicioso, habrá la menor cantidad de coincidencias posible, dejando oportunidades para las reglas de coincidencia posteriores.

Grupo

La agrupación es un artefacto muy útil en las expresiones regulares. ()El contenido entre paréntesis es un grupo. En las expresiones regulares, se expresa de esta forma:

/(\d*)([a-z]*)/

grupo de captura()

Usando grupos de captura, podemos capturar personajes clave.

Por ejemplo

var group = '123456789hahaha'.match(/(\d*)([a-z]*)/)

El grupo 1 se utiliza para hacer coincidir cualquier número de números y el grupo 2 se utiliza para hacer coincidir cualquier número de letras minúsculas.

Luego matchpodemos obtener los resultados coincidentes de estos dos grupos en el resultado de retorno del método, group[1]"123456789", group[2]"hahaha".

También podemos obtener el resultado del partido del grupo anterior en RegExpel atributo estático . . _ Pero no es estándar, aunque muchos navegadores lo han implementado, trate de no usarlo en un entorno de producción.$1~$99RegExp.$1"123456789"RegExp.$2"hahaha"RegExp.$1~$9

La aplicación de este tipo de grupo de captura es similar al replacemétodo de cadena, pero al llamar replaceal método, debemos referirnos al grupo a través $1de $2este formulario.$n

"123456789hahaha".replace(/(\d*)([a-z]*)/, "$1") // "123456789"

Usando $1, podemos reemplazar la cadena de origen con la cadena que coincide con el grupo 1, es decir "123456789".

Grupo sin captura (?:)

Un grupo que no captura es un grupo que no genera una referencia, también está ()entre paréntesis, pero el comienzo del paréntesis es ?:, es decir, /(?:\d*)/esta forma.

Echemos un vistazo al ejemplo anterior:

var group = '123456789hahaha'.match(/(?:\d*)([a-z]*)/)

Dado que los grupos que no capturan no generan referencias, lo group[1]es "hahaha"; de la misma manera, RegExp.$1lo es "hahaha".

Al ver esto, no puedo evitar preguntarme, ya que no necesito hacer referencia al grupo que no captura, ¿cuál es el punto del grupo que no captura?

Después de pensarlo un rato, creo que el grupo sin captura tiene las siguientes ventajas y necesidades:

  1. Un grupo que no captura es menos costoso en memoria que un grupo que captura porque no requiere que se genere una referencia.

  2. La agrupación se realiza para facilitar la adición de cuantificadores. Aunque no podemos generar referencias, si no hay agrupación no es conveniente añadir cuantificadores a un grupo de caracteres.

'1a2b3c...'.match(/(?:\d[a-z]){2,3}(\.+)/)

Cita\núm

Las expresiones regulares pueden hacer referencia a grupos anteriores con referencias. De esta forma \1, \2se puede hacer referencia a la subexpresión anterior.

Por ejemplo, si quiero hacer coincidir una cadena, debe cumplir las siguientes reglas:

La cadena comienza y termina con comillas simples o dobles, y el contenido del medio puede ser números o palabras.

Entonces lo que quiero asegurar es que el principio y el final sean comillas simples o dobles, por lo que mi patrón se puede escribir como:

var pattern = /^(["'])[a-z\d]*\1$/ pattern.test("'perfect123'") // true 

pattern.test('"1perfect2"') // true

aserción de ancho cero

Para ser honesto, cuando miré por primera vez el concepto y la explicación de las afirmaciones de ancho cero, realmente no entendí de qué estaba hablando.

  • Aserción de anticipación de ancho cero (?=)
  • Aserción de anticipación negativa de ancho cero (?!)
  • Aserción retrospectiva positiva de ancho cero (?<=)
  • Afirmación inversa negativa de ancho cero (?<!)

Más tarde, separé el vocabulario y agregué mi propio entendimiento, y gradualmente lo entendí un poco.

  • Ancho cero: ancho cero, la afirmación se utiliza como condición necesaria para la coincidencia, pero no se refleja en el resultado de la coincidencia.
  • Positivo: positivo, los caracteres de la afirmación deben coincidir.
  • Negativo: negativo, los caracteres de la afirmación no pueden coincidir.
  • Previsión: la previsión debe cumplir las condiciones del frente, las condiciones están en el frente y el frente es igual al lado derecho.
  • Fila trasera: mirando hacia atrás, debe cumplir con las condiciones de la parte trasera, la condición es en la parte trasera, la parte trasera es igual al lado izquierdo.

Aserción de anticipación de ancho cero (?=)

El carácter especificado debe existir a la derecha del objetivo de la restricción.

/123(?=a)/.test('123a') // true

El ejemplo anterior restringe 123la presencia del lado derecho a.

Aserción de anticipación negativa de ancho cero (?!)

El carácter especificado no puede existir en el lado derecho del objetivo de restricción.

/123(?!a)/.test('123a') // false

El ejemplo anterior restringe que 123no puede haber ninguno en el lado derecho a; de lo contrario, el resultado es false.

Aserción retrospectiva positiva de ancho cero (?<=)

El carácter especificado debe existir a la izquierda del objetivo de la restricción.

/(?<=a)123/.test('a123') // true

El ejemplo anterior restringe 123la presencia del lado izquierdo a.

Solo ES2018 admite afirmaciones de línea detrás de ancho cero

Afirmación inversa negativa de ancho cero (?<!)

El carácter especificado no puede existir en el lado izquierdo del objetivo de restricción.

/(?<!a)123/.test('a123') // false

El ejemplo anterior restringe que 123no puede haber ninguno en el lado izquierdo a; de lo contrario, el resultado esfalse

Nota: Esta función solo es compatible con ES2018.

ExpReg

Cuando se trata de expresiones regulares, tenemos que mencionar RegExplos objetos. A continuación, aprenderemos sobre los objetos desde varios aspectos, como métodos prototipo, propiedades estáticas y propiedades de instancia RegExp.

método prototipo

RegExp.prototipo.prueba

test()Es nuestro método regular más utilizado. test()El método realiza una recuperación para comprobar si la expresión regular coincide con la cadena especificada y devuelve un valor booleano trueo false.

Si la expresión regular tiene establecido el indicador global g, la ejecución test()cambiará RegExp.lastIndexel atributo utilizado para registrar el índice inicial del último carácter coincidente. Si el método se ejecuta continuamente test(), las ejecuciones posteriores lastIndexcoincidirán con la cadena que comienza desde este punto. En este caso, si test()el resultado no coincide, lastIndexse restablecerá a 0.

RegExp.prototipo.exec

exec()En comparación con test()obtener información de coincidencia más rica, el resultado es una matriz. El elemento 0 de la matriz es la cadena coincidente y los elementos del 1 al n son los ()resultados capturados mediante la agrupación entre paréntesis.

La matriz de resultados es una matriz y la matriz también son datos de tipo objeto, por lo que la matriz de resultados también tiene dos atributos: indexyinput

  • indexRepresenta el valor de índice basado en 0 del carácter coincidente en la cadena original.
  • inputluego representa la cadena original

De acuerdo con test()la expresión regular, si se establece el indicador , se actualizará gen cada ejecución .exec()lastIndex

propiedades estáticas

Las propiedades estáticas no pertenecen a ninguna instancia y se debe acceder a ellas a través del nombre de la clase.

Exp.reg.$1-$9

Se utiliza para obtener el resultado coincidente del grupo: RegExp.$1se obtiene el resultado coincidente del primer grupo RegExp.$9y se obtiene el resultado coincidente del noveno grupo.

Propiedades de instancia

último índice

lastIndex, entendido semánticamente, es el índice inicial del último carácter coincidente. Cabe señalar que esto sólo es efectivo si gla bandera está configurada lastIndex.

Cuando aún no hay ninguna coincidencia, lastIndexnaturalmente 0significa que la coincidencia comienza desde la enésima 0cadena.

lastIndexse actualizará como exec()el ytest()

var reg = /\d/g reg.lastIndex // 0 

reg.test('123456') reg.lastIndex // 1 

reg.exec('123456') reg.lastIndex // 2

lastIndexSe puede modificar manualmente, lo que significa que tienes control gratuito sobre los detalles del partido.

banderas

flagsLa propiedad devuelve una cadena que representa qué indicadores están habilitados para esta instancia de expresión regular.

var reg = /\d/ig reg.flags; // "gi"

global

globalEs un valor booleano que indica si la expresión regular utiliza gbanderas.

ignorar caso

ignoreCaseEs un valor booleano que indica si la expresión regular utiliza ibanderas.

multilínea

multilineEs un valor booleano que indica si la expresión regular utiliza mbanderas.

fuente

source, que significa fuente, es una representación de cadena de una expresión regular y no incluye barras a ambos lados del literal regular ni ningún carácter de bandera.

Métodos de cadena que implican regularidad.

Cadena.prototipo.búsqueda

search()El método realiza una coincidencia en un objeto de cadena utilizando una expresión regular y devuelve un indexíndice que representa la primera coincidencia de la expresión regular en la cadena. Si no se encuentra ninguna coincidencia, devuelva -1.

search()El parámetro del método debe ser una expresión regular; de lo contrario, se convertirá new RegExp()silenciosamente en un objeto de expresión regular.

"123abc".search(/[a-z]/); // 3

Cadena.prototipo.coincidencia

El método de cadena se utiliza para recuperar cadenas y es similar al método matchde expresión regular . También es necesario que los parámetros del método sean expresiones regulares. El método devuelve una matriz.execmatchmatch

exec()La diferencia entre y es que si la matchexpresión regular pasada por el método está marcada g, se devolverán todos los resultados que coincidan con la expresión regular completa, pero no se devolverá el grupo de captura.

"123abc456".match(/([a-z])/g); 

// 返回["a", "b", "c"] 
var reg = /([a-z])/g; reg.exec('123abc456');

// 返回数组
["a", "a", index: 3, input: "123abc456", groups: undefined] reg.exec('123abc456'); 

// 返回数组
["b", "b", index: 4, input: "123abc456", groups: undefined] reg.exec('123abc456'); 

// 返回数组
["c", "c", index: 5, input: "123abc456", groups: undefined]

Si match()la expresión regular pasada por el método no tiene un indicador g, el comportamiento exec()es consistente con el método y solo se devolverá el primer resultado coincidente y el resultado capturado agrupado.

Si hay una agrupación entre paréntesis en la expresión en este momento, match()los resultados de estas coincidencias de agrupación también se pueden obtener en la matriz de resultados, lo que también se menciona en el grupo de captura.

"123abc456".match(/([a-z])/); // 返回["a", "a", index: 3, input: "123abc456", groups: undefined] RegExp.$1; // "a"

Cadena.prototipo.reemplazar

replace()Es un método de reemplazo de cadenas, no requiere que el primer parámetro sea una expresión regular. Si el primer parámetro es una expresión regular y contiene agrupación, en el replace()segundo parámetro, se puede hacer referencia al resultado de la coincidencia de agrupación "$1"de "$2"esta forma.

"123456789hahaha".replace(/(\d*)([a-z]*)/, "$1") // "123456789"

Cadena.prototipo.split

split()El método es el método de división de cadenas, que también es un método de uso común, pero muchas personas no saben que puede aceptar expresiones regulares como parámetros.

Supongamos que obtenemos una cadena tan irregular "1,2, 3 ,4, 5"y luego necesitamos dividir la cadena para obtener una matriz de números puros. split(",")No es posible usarlo directamente, pero se puede hacer usando expresiones regulares como condiciones de división.

var str = "1,2, 3 ,4, 5"; str.split(/\s*,\s*/); // 返回 ["1", "2", "3", "4", "5"]

por fin

Las expresiones regulares son un punto de conocimiento muy importante pero que fácilmente se pasa por alto, y también es un punto de prueba frecuente en las entrevistas, por lo que se le debe prestar suficiente atención. Después de resolver los puntos de conocimiento anteriores, creo que puedo estar seguro y tranquilo en el combate real posterior.

Viene con 250 conjuntos de códigos fuente de proyectos seleccionados.

Captura de pantalla del código fuente

Adquisición del código fuente: siga la cuenta pública "Coder Park" y responda [código fuente] para obtener el conjunto completo de enlaces de descarga del código fuente.

Supongo que te gusta

Origin blog.csdn.net/lwzhang1101/article/details/135401372
Recomendado
Clasificación