马黑黑 发表于 2023-1-14 10:04

通过一个式子聊聊正则表达式

本帖最后由 马黑黑 于 2023-1-14 10:15 编辑

用正则表达式去匹配特定字符,目的在于找出匹配的字符或字符串,并对之进行替换或做其他操作。这种情形,我们就需要在构造正则表达式之时就设定好捕获组,随后使用特定方式将匹配结果按分组对应取出。

在正则里,分组用圆括号表示。试看以下式子:

({3})ABC$

绿色部分, 表示字符限定,表示这里可以出现的是 0 到 9 的数字,{3} 用于限制 的出现次数,只能出现 3 个数字,这 3 个数字是 0-9 之间的任意组合,包括重复组合,反正 {3} 只限定一个内容:方括号里的字符要出现 3 次。{3} 合起来的意思是:数字出现3次。圆括号则将其包裹在内,在这里表示用于将来的引用。为什么要这么做?因为,匹配的具体数字是哪几个是不确定的,我们只知道有三个数字必须出现,仅此而已,将来我们可能要一一取出这些数字,这叫引用,引用之时,因为用了圆括号将其分组了,可以对应获取出来。

式子中的 ABC 是字面字符,它们代表它们自己,就是 ABC,没必要分组,因为它们不会改变;$ 有特殊含义,表示屁股,就是字符串的末尾处。

针对上述式子,以下字符串会与之匹配吗?

    ck002ABCFG
    befGG112ABC
    006ABC
    贵龙3907ABC

第一个,ck002ABCFG,002匹配{3},但ABC后面还有字符,式子中的 ABC$ 带屁股,$ 表示到了 ABC 就不能有后续字符了。整体不匹配。

第二个,befGG112ABC,标准匹配。

第三个,006ABC,标准匹配。

第四个,贵龙3907ABC,这是一个难题。很多人第一感觉是,4个数,不匹配。错了,这句是匹配的,907ABC 匹配 ({3})ABC$ 。({3})ABC$这个正则表达式没有规定前面的字符是什么,它只规定 ABC 之前有三个数字,ABC之后是屁股。如此,第四个字符串是匹配的。

以上是关于匹配方面的讨论,最后给一个示例,取出字符串中不确定具体内容但知道其组成规则的字符串:

      letstr = 'GV3057KL';
      let ru = /(^{2})({4})({2}$)/;

      let res = str.match(ru);
      if(res !== null) {
                console.log(res);
      } else {
                console.log('未找到匹配项');
      }


上面代码:

我们先给出一个待检测的字符串,这个字符串随后可以更改以便检验我们的代码。

第二句,我们构建一个正则表达式,用圆括号分成三组,头尾两组都是两个大写字母,唯一不同是头部的两个大写字母之前有一个符号 ^ ,表示是字符串的开头,尾部两个大写字母带一个 $,屁股。中间是四个数字。

第三句,用 match() 方法去匹配正则,match() 的语法是:待检字符串.match(正则表达式) 。我们将检测结果赋予了变量 res ,res 将得到两个可能的结果,其一 null,啥也没有,因为不匹配,其二是一个数组,这个数组包含了正则表达式里的分组,数组的下标在正则里从 1 开始,这与JS数组从 0 开始不一样。

if ... else ... 判断语句,检测结果若返回值不是 null,则取出结果的第二个并console.log 出来,console.log(res);,否则,若为 null,给出未找到匹配的提示。

梦油 发表于 2023-1-14 10:14

黑黑先生小年快乐!

马黑黑 发表于 2023-1-14 10:18

梦油 发表于 2023-1-14 10:14
黑黑先生小年快乐!

{:4_190:}

梦油 发表于 2023-1-14 10:23

我不懂“正则表达式”。我为帖子加分,是因为,今天是小年,黑黑先生仍笔耕不辍,为大家传授知识,实在是辛苦了。

马黑黑 发表于 2023-1-14 11:32

梦油 发表于 2023-1-14 10:23
我不懂“正则表达式”。我为帖子加分,是因为,今天是小年,黑黑先生仍笔耕不辍,为大家传授知识,实在是辛 ...

{:4_191:}

梦油 发表于 2023-1-14 13:01

马黑黑 发表于 2023-1-14 10:18


{:4_180:}

梦油 发表于 2023-1-14 13:02

马黑黑 发表于 2023-1-14 11:32


{:4_176:}

红影 发表于 2023-1-14 13:19

console.log(res);是取出结果的第二个,和({3})ABC$不一样,这个是前面是0-9的任意3个。
是这样理解吧?

红影 发表于 2023-1-14 13:19

为什么这个里面没有转义符了?

红影 发表于 2023-1-14 13:21

有点迷糊,看这个 let ru = /(^{2})({4})({2}$)/;,取出的地二个是不是A-Z的某一个?

马黑黑 发表于 2023-1-14 14:53

红影 发表于 2023-1-14 13:21
有点迷糊,看这个 let ru = /(^{2})({4})({2}$)/;,取出的地二个是不是A-Z的某一个?

正则的分组是,(1)(2)(3),具体为:

一组是:^{2}
二组是:{4}
三组是:{2}$

如果匹配,我们取出的是第二组所描述的在原字符串中的字符,即4个数字。

马黑黑 发表于 2023-1-14 14:55

红影 发表于 2023-1-14 13:19
为什么这个里面没有转义符了?
碰上必须转义的符号才会用转义符,需要转义的字符其实并不多(有特殊用途的,如 \ 和 [ 等,如果要用它们自身的字面量去做匹配,就需要转义)。

马黑黑 发表于 2023-1-14 14:57

红影 发表于 2023-1-14 13:19
console.log(res);是取出结果的第二个,和({3})ABC$不一样,这个是前面是0-9的任意3个。
是这样理 ...

res 变量是检索结果的存放数组变量,它和正则无关。

{3} 是正则表达式的子式子,与res无关。

红影 发表于 2023-1-14 23:46

马黑黑 发表于 2023-1-14 14:53
正则的分组是,(1)(2)(3),具体为:

一组是:^{2}


原来取的是第二组。

红影 发表于 2023-1-14 23:47

马黑黑 发表于 2023-1-14 14:55
碰上必须转义的符号才会用转义符,需要转义的字符其实并不多(有特殊用途的,如 \ 和 [ 等,如果要用它们 ...

还以为JS里的都是必须的。

红影 发表于 2023-1-14 23:48

马黑黑 发表于 2023-1-14 14:57
res 变量是检索结果的存放数组变量,它和正则无关。

{3} 是正则表达式的子式子,与res无关。

哦哦,我又理解错了{:4_173:}

马黑黑 发表于 2023-1-15 08:50

红影 发表于 2023-1-14 23:48
哦哦,我又理解错了

这里面涉及两个层面:一个是正则表达式,一个是JS对正则表达式的应用。

二者当然不是决然没有关系。但你对它们的理解混在一起了,所以我的回复说没有关系。正则表达式要用正则的规则去理解,JS用正则检索到的结果数组,要用JS的理论去理解。

马黑黑 发表于 2023-1-15 08:54

红影 发表于 2023-1-14 23:47
还以为JS里的都是必须的。

需要转义:
一是正则表达式的元字符,它们是这些——

$, (, ), *, +, ., [, ], ?, \, ^, {, }, |


二是部分不转义JS会报错的JS保留字符,比如 // 用于JS的注释,也是构建正则表达式的符号 /正则表达式/ ,有时候匹配符号 / 不做转义会报错。

马黑黑 发表于 2023-1-15 08:56

红影 发表于 2023-1-14 23:46
原来取的是第二组。

规则多,有正则的,有JS的,容易混在一起

红影 发表于 2023-1-15 11:08

马黑黑 发表于 2023-1-15 08:50
这里面涉及两个层面:一个是正则表达式,一个是JS对正则表达式的应用。

二者当然不是决然没有关系。但 ...

嗯嗯,我之前的确理解错了。这是两件事,我混到一起去了{:4_204:}
页: [1] 2 3 4
查看完整版本: 通过一个式子聊聊正则表达式