Un texto para descifrar contraseñas regulares

Zhiyuan Wang, Departamento de Tecnología Front-end de WeDoctor

prefacio

Extraños habituales y familiares, lo vemos en la verificación de formularios, y también lo vemos en el principio del analizador del marco fuente html a ast tree; a menudo visto, Baidu busca cuando es necesario, se puede usar, pero la razón es muy simple ¡Quién puede entender este texto marciano!

​ El objetivo de este artículo es llevarte al mundo normal. Como un artículo de divulgación científica serio y responsable, debe hacerse para que puedas aprenderlo una y otra vez pero no, así que ven y revísalo una y otra vez.

1651cbfd336d45bb12a38491cc85061d

historia regular

La regularidad es en realidad el establecimiento de reglas, que se utilizan para verificar u obtener información.

Realmente se originó a partir de redes neuronales

En la década de 1940, dos neurofisiólogos desarrollaron un método para describir matemáticamente las redes neuronales y publicaron un artículo "Algoritmo de búsqueda de expresiones regulares" en 1956, que describía principalmente un método llamado "Algoritmo de búsqueda de expresiones regulares".

Da un gran salto en el mundo de la informática

Diez años más tarde, en 1968, el padre de UNIX publicó el artículo "Algoritmo de búsqueda de expresiones regulares" y trasplantó las expresiones regulares a la famosa herramienta de búsqueda de texto grep.

bfd01186db5e7514349f9b7146cdb437

¿Por qué existe la expresión regular?

Para entender algo, no memorices la API de la capa de aplicación tan pronto como apareces, pero para entender, el cerebro humano está originalmente diseñado para ser fácil de memorizar las cosas que entiende, así que no desperdicies tu talento.

​ Hemos dicho que la regularidad es en realidad el establecimiento de reglas, que se utilizan para verificar u obtener información. La acción de emparejamiento más grosera es, sin duda, la correspondencia uno a uno, a a a, b a b, esta regla es exactamente la misma para emparejar, pero esto es sin duda demasiado ineficiente; una cosa es fácil de tener algo en común, y lo común constituye un conjunto, como el número de teléfono móvil de 13 dígitos, los buzones de correo con @, etc., la regularidad es para permitirnos hacer coincidir de manera más eficiente u obtener la existencia de estos conjuntos de reglas específicas.

9e9f10a0-56d4-4089-93a0-559f7f27ed51.jpg

cómo hacerlo

​ La forma de procesamiento en regular es establecer subreglas, de modo que algunos símbolos ya no se representen a sí mismos, sino algunas subreglas, al igual que construir un edificio, si queremos encontrar las reglas que queremos, tenemos que usar el ladrillos mínimos apropiados, y luego establezca la cantidad de uso, y la construcción está completa.

​ 这个子规则,就是元字符,如我们常见的\d,代表单个0-1数字,\s就是换行指标等空白字符;需要注意的是,我们刚刚一直在强调单个,这其实也很好理解,对于文本而言,最小单元自然是单个字符,有了最小单元,我们再加上重复规模,就可以搭建我们自己的大楼了。 ​

至此,我们对正则世界基本的了解算是到位了,开始更接地气的分享叭!

e1f7a1a7-82cc-4f47-a0d5-e7ebe5d32dc9.jpg

砖块:元字符

​ 那我们先来了解元字符,有四个维度,分别是【字符组】、【取反字符组】、【常用字符组】、【空白字符】,可以记忆为 【3 + 1】,依次理解

imagen-20220324101825984

字符组

基础使用

​ 对于单字符选择而言,在正则中的术语被称为字符组,接下来我们都会用这个术语,但不要被迷惑,它并不是匹配一组数据,而只是匹配一组数据中的一个字符,这点很关键。

语法: [xxx]

匹配规则: 目标文本需包含【任意一个包含在括号中的元素】

**获取信息规则:**将获取第一个【任意一个包含在括号中的元素】

举例: /[abc]/这个正则将匹配a、b、c中的任何一位且只有一位,默认匹配第一位,使用测试平台会得到如下结果

imagen-20211212101306259

取反字符组

取反逻辑

​ 正常使用是范围内选取,不过也会出现【除了这些之外】的范围选取,这时就需要用到取反了

语法: [^xxx]

匹配规则: 目标文本需包含【任意一个不包含在括号中的元素】

**获取信息规则:**将获取第一个【任意一个不包含在括号中的元素】

举例: /[^abc]/这个正则将匹配非a、b、c中的任何一位且只有一位,默认匹配第一位,使用测试平台会得到如下结果

imagen-20211212101843011

常用字符组

八二原则同样适用在字符组中,有很多常见的匹配规则,没必要重复写,于是正则就把这些特殊字符组分别取了个别名

imagen-20211212102101853

主要分为如下【3+1】概念,三对+一个

使用符号 规则 对应字符组
\d 单个数字 [0-9] (digit数字)
\D 单个任意非数字 [^0-9]
\w 单个任意数字字母下划线 [0-9a-zA-Z_] 数字字符下划线
\W 单个任意非数字字母下划线 [^0-9a-zA-Z_] 非单词字符
\s 单个任意空白符 [ \t\v\n\r\f] 表示空白符 (空格、水平制表符、垂直制表符、换行符、回车符、换页符)
\S 单个任意非空白符 [^ \t\v\n\r\f]
. 单个除换行符外任意字符 [^\n\r\u2020\u2029] 通配符 除换行符、回车符、行分隔符、段分隔符外任意字符

其他常用字符组

对应字符组 规则
[\d\D] | [\s\S] | [\w\W] | [^] 任意字符

空白字符

​ 这类字符比较特殊,单独拎出来,方便后期直接使用

imagen-20211212102918646

​ 到此,我们也就知道了如何去匹配单个字符,这就是我们的“最小规模”,但一个个匹配肯定是不行,那正则将冗长到难以忍受,所以我们还需要重复,这就是量词的作用。

要多少块砖:量词

​ 理解了字符组,我们就要了解规模了,这在正则中有个术语 --- 量词,还是【3+1】,依次理解

imagen-20220324101943024

这个没有很复杂的东西,唯一要注意的是,正则默认是只匹配一次的,即一次匹配完后就算后文还有符合的内容也不再获取,这涉及到修饰符g,后面再补充;

​ 看案例就行,我们还是以[abc]作为字符组最小单元来演示。

*号:0-n次

正则: /[abc]*/

匹配规则: 目标文本无需包含【任意一个包含在括号中的元素】,此匹配规则一定成立

imagen-20211212105956356

**获取信息规则:**将获取第一段【包含在括号中且连续的元素组】

image-20211212104426218

+号:1+n次

正则: /[abc]+/

**获取信息规则:**将获取第一段【包含在括号中且连续的元素组】

image-20211212105920428

匹配规则: 目标文本需包含【至少一个包含在括号中的元素】

image-20211212105824231

?号:0次或1次

正则: /[abc]?/

**匹配规则:**此匹配规则一定成立

image-20211212110246348

**获取信息规则:**将获取第一个【任意一个包含在括号中的元素】

image-20211212110346923

{}符号:精确控制次数

​ 上面其实都属于特殊案例,我们可以通过{}精确控制匹配次数,主要有三个用法

  • {m}:必须出现m次
  • {m, n}:可以出现m-n次
  • {m,}:至少出现m次

我们对这三种情况进行演示,动图如下

2021-12-12 11.07.50

量词模式

量词还涉及到模式问题,因为量词有范围,这就意味着可取多可取少,但计算机是不允许有歧义的,所以量词存在三种模式

  • 贪婪模式:默认,会尽可能匹配多的内容
  • 懒惰模式:量词后面加个?,会尽可能少匹配内容
  • 独占模式:量词后面加个+,不触发回溯动作

image-20220324102002611

举例见模式区别

测试用例: aaabb

测试正则:

  • 贪婪模式:/a*/
  • 懒惰模式: /a*?/
贪婪模式:/a*/

匹配过程:

image-20211212225721609

匹配结果:

image-20211212225241752

对应输出结果: ['aaa','','','']

懒惰模式: /a*?/

匹配过程:

匹配结果:

image-20211212225648159

对应输出结果: ['','a','','a','','a','','','']

补充案例

image-20211212122958012

至此,我们就完成了对量词规则的学习

正则模式

既然量词有模式,正则本身自然也有模式,针对【大小写、多行、点通配、备注】情况,存在【3+1】种模式

  • 不区分大小写模式
  • 点通配模式
  • 多行匹配模式
  • 注释模式

我们来逐一了解

image-20220324102025646

不区分大小写模式(Case-Insensitive)

语法: /(?i)reg/ 对应js为 /reg/i

注意点:

  1. 不区分大小写模式的指定方式,使用模式修饰符 (?i);
  2. 修饰符如果在括号内,作用范围是这个括号内的正则,而不是整个正则;

作用: 忽略大小写进行匹配

正则: /(?i)(cat) \1/ 对应js为 /(cat) \1/i

image-20211213172146873

如果这时候我们希望重复单词间保持大小写完全一致,可以使用如下正则

正则: /((?i)cat) \1/ 对应js为 暂无

image-20211213172352390

点通配模式(单行匹配模式 -- Single Line)

语法: /(?s)reg/ 对应js为暂无

注意点:

作用: 使得.元字符可以匹配包括换行在内的所有字符

image-20211213173307910

多行匹配模式

语法: /(?m)reg/ 对应js为/reg/m

注意点:

作用: 使得^$可以匹配上每行的开头或结尾

使用前正则: /^the|cat$/

image-20211213173510339

使用后正则: /(?m)^the|cat$/ 对应js为/^the|cat$/m

image-20211213173641217

注释模式

语法: /(?#)reg/ 对应js为 暂无

注意点:

作用: 使得正则支持添加备注信息

使用正则案例: /(\w+)(?#word) \1(?#word repeat again)/

正则位置信息

​ 对于匹配而言,就像我们看一个人是不是自己要找的人,不只有对着画像、照片一直看这一个方法,也可以描述TA在什么东西的旁边、TA面前是什么、背后是什么等等,这些位置信息在正则中同样有需求,并且有个专门的术语 -- 断言

​ 断言,即断定匹配文本的位置关系;前后的内容是什么、中止的位置在哪之类,落实下来分为三类:单词边界行的开始/结束环视

image-20220324102049287

行的开始/结束

​ 这个我们或多或少都接触过,如果我们要求匹配的内容出现在一行文本的开头或结尾,就可以使用^$进行位置界定。

​ 结合之前说的【模式】中多行模式的概念,默认处理文本会被正则当成一行进行处理,无论其是否换行,这是的开始结束就等同于文首和文末;而如果想处理多行情况,只需要改变模式为多行匹配即可,js中语法为/reg/m

单词边界(Word Boundary)

​ 多行模式+^$可以在行的维度处理边界问题,但如果是单词,就无能为力了,如我们希望在下面文本中替换tom这个人名为jerry

tom asked me if I would go fishing with him tomorrow.
复制代码

这时如果替换的正则是/tom/ ,就会出现这种错误的替换现象

image-20211214081357369

很明显,我们要的就是tom,而并不是只要包含tom就可以的部分,这时我们就可以使用到单词边界的概念,设定开始截止,避免出现匹配歧义。

基础概念

语法: \b

作用: 匹配到\w即【[A-Za-z0-9_]】表示范围之外的字符就中止匹配,可以理解为边界(Boundary)

实例

image-20211214081830692

环视

​ 我们刚刚说了边界,包括单词和行的边界,其实边界也就是要求匹配文本的前后一定是特定的内容,只是这个特定内容对行来说是^$,对单词边界来说是$

​ 那我们把这个特定范围再灵活点,对于一段内容而言,有前后两个方向、满足或者不满足两个情况,意味着有四种情况,如下表。

image-20211214082413126

总结下来其实就是:有尖括号则为左,等号肯定感叹否

正则逻辑信息

根据前文,我们已经学习了【字符组】和【量词】的概念,就像一门编程语言,有组成物料还不够,自然还需要一些逻辑判断,在正则中也存在【逻辑元字符】这一概念。

逻辑元字符

image-20211212115541866

|号:或逻辑

某个资源可能以 http:// 开头,或者 https:// 开头,也可能以 ftp:// 开头,那么资源的 协议部分,我们可以使用 (https?|ftp):// 来表示。

image-20211212115704093

正则优先级提升之分组

在正则中存在分组的概念,主要有两点作用:整体和复用。

image-20220324102130482

整体

​ 代表避免语义分析有歧义,如【匹配15位数字或18位数字】,这时如果写出这样的正则/\d{15}\d{3}?/;后面的\d{3}?将代表懒惰模式匹配,这个正则会只匹配18位数字而非15位

测试正则: /\d{15}\d{3}?/

image-20211213092222826

​ 这里就存在确定\d{3}是一个整体的需求,这可以使用分组实现

测试正则: /\d{15}(\d{3})?/

image-20211213092457788

复用

​ 有些时候,我们也会需要用到之前匹配到的结果,如【查看文本中的连续重复单词】,解决思路就变成了

  1. 写出匹配单个单词的正则

  2. 使用之前的结果进行再次匹配

    第二点,就是通过分组实现的;先了解下基础概念

基础概念

语法: 定义使用() ,正则中访问使用\编号,方法中访问使用$编号

作用: 用于分组,被括号括起来的部分默认将被保存为子组,正则中可以通过子组编号访问,子组编号从一递增,也可以用语法(?:)从而不保存子组,避免占用编号。

分组引用语法详解

分组引用

​ 假定分组编号为number,则可以使用\number进行引用

image-20211213110357843

多编号情况

左括号是第几个,那就是第几个分组

image-20211213105420673

不保存子组

使用此语法后不会为这个子组分配编号

image-20211213105522366

替换功能

image-20211213112012964

命名分组

​ V8 目前已经完全实现了命名捕获分组的提案 tc39.github.io/proposal-re…

基础概念

语法: 定义使用(?<name>) ,正则中访问使用\k<name>,方法中访问使用$<name>

作用: 用于命名分组,不再使用编号访问而是直接通过分组变量名访问,更加准确

image-20211213110852724

API结合解构赋值

​ 在js关于正则的方法中,如果存在命名分组,会存在groups属性,里面存放着每个命名分组的名称以及它们匹配到的值;结合解构赋值,会有很神奇的功效;

在 exec() 和 match() 中的使用:

​ exec() 和 match() 方法返回的匹配结果数组上多了一个 groups 属性,里面存放着每个命名分组的名称以及它们匹配到的值

const {day, month, year} = "04-25-2017".match(/(?<month>\d{2})-(?<day>\d{2})-(?<year>\d{4})/).groups 
复制代码

image-20211213111241405

在 replace(/.../, replacement) 中的使用:

​ 当replacement为函数时,在实参列表的最末尾,多传了一个 groups 对象

"04-25-2017".replace(/(?<month>\d{2})-(?<day>\d{2})-(?<year>\d{4})/, (...args) => {
  const groups = args.slice(-1)[0]
  const {day, month, year} = groups
  return `${day}-${month}-${year}`
}) 
复制代码

image-20211213111755614

正则编程

​ 这是最最关键的部分,学来就得用上呀,我们来分享在正则在前端编程中的应用。

正则最终还是要落实到编程语言中来,让我们来看下正则编程吧!

​ 正则的处理可以区分为如下四类:

  • 校验文本内容
  • 提取文本内容
  • 替换文本内容
  • 切割文本内容

让我们逐一了解

校验文本内容

**需注意:**关于lastIndex,即正则会将下一次匹配开始的位置 ;字符串的四个方法,每次匹配都是从0开始的,即lastIndex不变;而正则的两个方法exec和test ,如果是全局匹配,则每次匹配完都会改变lastIndex的值,这就会导致可能出现【处理两次,第一次成功,第二次失败】的情况。

var regex = new RegExp(/^\d{4}-\d{2}-\d{2}/, 'g')
regex.test('2021-12-21') // true
console.log(regex.lastIndex ) // 10
regex.test('2021-12-21') // false
console.log(regex.lastIndex ) // 0
复制代码

由于我们这里是文本校验,并不需要找出所有的。所以建议JavaScript 中文本校验在使用 RegExp 时不要设置 g 模式。

字符串方法:search

search 会将字符串转为正则

image-20211222081656511

正则方法:test

image-20211222081801572

提取文本内容

字符串方法:match

match 会将字符串转为正则

**注意:**match 方法的返回值与修饰符g有关(没有匹配上时返回null)

  • 没有 g : 返回标准匹配格式,即:数组的第一个元素是整体匹配的内容,接下来是分组捕获的内容,然后是整体匹配的第一个下标,最后是目标字符串

  • 有g :返回的是一个包含所有匹配内容的数组

image-20211222080722643

正则方法:exec

​ exec 比 match 更强大,可以解决 有修饰符g时match没有索引信息的问题,在使用exec时,正则会将下一次匹配开始的位置存放在正则的属性lastIndex上

image-20200429092804208

image-20211222082956151

替换文本内容

字符串方法:replace

image-20211222080844970

image-20211222082240149

切割文本内容

字符串方法:split
  • 可以有第二个参数,表示结果数组的最大长度
  • 如果正则使用分组时,结果数组中是包含分隔符的

image-20211222081252051

前端相关API总结

  • string
    • match
    • split
    • search
    • replace
  • RegExp
    • test
    • exec

总结

做下总结吧,绘制知识图谱,方便自己记忆,也方便和人分享

3 + 1 元字符;3 + 1 常用元字符;3 + 1 正则量词;3 量词匹配模式;3 + 1 正则匹配模式;3 + 1 正则逻辑

En primer lugar, el metacarácter material tiene cuatro dimensiones, a saber, [grupo de caracteres], [grupo de caracteres inversos], [grupo de caracteres comunes], [carácter en blanco], que se pueden memorizar como [3 + 1];

Después de comprender el grupo de caracteres, debemos comprender la escala, que tiene un término en expresiones regulares: los cuantificadores siguen siendo [3+1];

Los cuantificadores también implican el problema de los patrones, porque los cuantificadores tienen un rango, lo que significa más y menos deseable, pero las computadoras no permiten la ambigüedad, por lo que hay tres modos de cuantificadores;

Dado que el cuantificador tiene un patrón, el regular en sí mismo naturalmente también tiene un patrón.Para el caso de [caso, multilínea, punto comodín, comentarios], hay [3+1] modos;

Al igual que el posicionamiento, no solo necesita su propia información absoluta, sino que también necesita mirar su información de posición relativa. Esta información se llama aserción en la regularización. Hay tres situaciones, [comienzo y final de línea, límite de palabra y mirar alrededor] , en el que mirar alrededor existe un antes y un después, no cuatro casos

Al igual que un lenguaje de programación, no es suficiente tener materiales fragmentados, también necesitamos lógica. Hay declaraciones de rama y grupos de prioridad en expresiones regulares |, y hay tres tipos de grupos, agrupación predeterminada, agrupación sin captura y agrupación con nombre. .

¡Hasta ahora, hemos resumido el contexto general de la regularidad con una oración de resumen muy concisa!

e31b505d9149743e24ad72c8cb787818

final

​ Adolescentes, la mente se ha fijado, quítenla y gracias, espero poder hacer que lo entiendan una vez y lo olviden, deben repetirlo de principio a fin, traten de realizarlo ustedes mismos, algunas necesidades encontrarán que si usas una perspectiva regular. Habrá muchas maneras asombrosas de lograrlo, y si puedes ayudar a otros, será muy gratificante.

img

Supongo que te gusta

Origin juejin.im/post/7078734381396787237
Recomendado
Clasificación