还不会正则表达式? 放心 我会出手(万字教学)

举报
坚毅的小解同志 发表于 2022/11/21 18:46:07 2022/11/21
【摘要】 还不会正则表达式? 放心 我会出手(万字教学)

体验正则表达式的能力

在一堆字符串中,获取里面的数字。

  普通代码

  let hd = 'jianyidexiaoxietongzhi2548564';
    let numstr = [...hd].filter(item => !Number.isNaN(parseInt(item)));
    console.log(numstr);

  正则表达式代码

  let hd = 'jianyidexiaoxietongzhi2548564';
    console.log(hd.match(/\d/g));

创建正则表达式

  使用字面量的方式

    优点

方便快捷,便于书写使用。

//建立一个字符串变量
let hd = 'jianyidexiaoxietongzhi';
//字面量创建正则
let rex = /j/;
//test 是一个正则方法,判断正则表达式是否能在字符串中匹配到内容,返回值是布尔值
console.log(rex.test(hd));

    缺点

正则表达式只可以匹配表面的字符串。获取不到变量

//建立一个字符串变量
let hd = 'jianyidexiaoxietongzhi123';
//字面量创建正则
let j = '1';
let rex = /j/;
//match 是一个字符串方法,前面的字符串包不包含扩内的的正则表达式,包含的话则返回值,没有的话返回null
console.log(hd.match(rex));

获取到的是变量j字符串,而不是变量j里的具体内容。
在这里插入图片描述

使用eval方法和模板字符串解决问题不大

//建立一个字符串变量
let hd = 'jianyidexiaoxietongzhi123';
//字面量创建正则
let j = '1';
let rex = `/${j}/`;
//使用模板字符串获得变量的值,在使用eval获取返回值
console.log(hd.match(eval(rex)));

在这里插入图片描述

  使用对象创建正则表达式

//不需要写/ /直接写正则内容即可
let hd = 'jianyidexiaoxietongzhi'
//使用对象的方式创建正则
let reg = new RegExp('d', 'g');
console.log(hd.match(reg));

对象创建的正则也可以直接识别变量,
注意使用对象创建的时候 写相关标识符的时候比如\d需要写成\ \d 写两个\才有效果,字符串里面一个\只代表一个普通文本。

let hd = 'jianyidexiaoxietongzhi'
//使用对象的方式创建正则
let d = 'j'
let reg = new RegExp(d, 'g');
console.log(hd.match(reg));

方法

  正则表达式的两个方法

    test

判断正则表达式中的内容是否包含在字符串中,无论在什么位置,返回值是逻辑值,true或false

let str = /xiaoxie/;
console.log(str.test('jianyidexiaoxietongzhi'));

在这里插入图片描述

    exec

从字符串中获取符合正则表达式规则的部分片段,返回值是捕获的字符串等相关内容,没有捕获到则返回null。

      没有捕获到

let str = /xiaoxie/;
console.log(str.exec('jianyidexaoxietongzhi'));

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-raUNbVIX-1667994349616)(2022-11-07-09-39-35.png)]

      捕获到

let str = /xiaoxie/;
console.log(str.exec('jianyidexiaoxietongzhi'));

返回捕获到的字符串 以及字符串开始的索引位置,和原字符串,只会匹配到第一次符合规则的字符串。

在这里插入图片描述

特殊字符

  基础元字符

\s

表示匹配一个空格字符,等价于‘ ’。

let rex = /\s/
console.log(rex.test('   d'));

在这里插入图片描述

\S

表示匹配一个非空格字符,字符串里面需要至少一个非空格字符

let rex = /\S/;
console.log(rex.test('   x'));

在这里插入图片描述

\t

表示匹配一个tab字符,字符串里面需要至少一个tab字符,

let rex = /\t/;
//两个空格
console.log(rex.test('  '));
//一个tab建
console.log(rex.test('	'));

在这里插入图片描述

\d

表示匹配数字0到9,字符串必须包含一个数字。

let rex = /\d/;
console.log(rex.test('dsad5'));

在这里插入图片描述

\D

表示匹配一个非数字,字符串中必须包含一个非数字内容。

let rex = /\D/;
console.log(rex.test('45645s45612'));

在这里插入图片描述

\w

表示匹配数字,字母,下划线,三种字符。

let rex = /\w/;
console.log(rex.test('sd45_'));

在这里插入图片描述

\W

表示匹配非数字,字母,下划线以外的三种字符。

let rex = /\W/;
console.log(rex.test('sd45_'));

在这里插入图片描述

.

表示非换行字符,有换行\n以外的字符就返回true。

let rex = /x/;
console.log(rex.test('\n'));

在这里插入图片描述

\

表示转义符号,将有意义的转无意义的内容,无意义的转有意义的内容。

let rex = /\./;
//点原本表示非换行符,通过转义符 变成了匹配一个.。
console.log(rex.test('.'));

在这里插入图片描述

  边界元字符

用来控制开头结尾内容的元字符。

^

表示匹配字符的开头内容。

let rex = /^xiao/;
//返回false   开头需要是xiao而不是xxiao。
console.log(rex.test('xxiaoxie')); 

$

表示匹配字符的结尾内容

//表示开头到结尾 为两个数字
let rex = /^\d\d$/;
console.log(rex.test('13')); 

在这里插入图片描述

  限定符

写在元字符,或者普通字符后面,用来限定次数的符号。

*

表示需要匹配到0到多个指定字符。

//表示需要匹配到任意个数字字符串。
let rex = /^\d*$/;
console.log(rex.test('154544'));   true
console.log(rex.test(''));    true

+

表示需要匹配到1到多个指定字符。

let rex = /^\d+$/;
console.log(rex.test(''));  false
console.log(rex.test('123'));  true

?

表示需要匹配到0到一次指定字符。

//字符串中需要有0到1个数字。
let rex = /\d?/;
console.log(rex.test('sdfsf'));    true
console.log(rex.test('sdf123sf')); true

{n}

表示需要匹配到指定次数的指定字符。

//连续五个数字字符串
let rex = /\d{5}/;
console.log(rex.test('sddsg458'));   false
console.log(rex.test('sddsg45458'));   true

{n,}

表示需要匹配到n到多次的指定字符。

let rex = /\d{5,}/;
console.log(rex.test('12d24545'));   true
console.log(rex.test('12d245'));   false

{n,m}

表示需要匹配到n到m次指定字符串。

let rex = /\d{2,3}/;
//是匹配的内容 而不是控制字符串中数字的内容,需要匹配到至少两个数字,只有一个则返回false,有五个数字,则从里面匹配三个数字,返回true。
console.log(rex.test('1ds'));   false
console.log(rex.test('45465'));  true

  贪婪和非贪婪

    贪婪

当我们使用限定符,捕获字符的时候,它会尽可能的从多捕获,这就是正则的贪婪性。

let rex = /\d{1,5}/
console.log(rex.exec('45684'));

在这里插入图片描述

    非贪婪

我们只需要在限定符后面再加个?就是非贪婪限定符了,它会优先选择最少的而不是多的。

let rex = /\d{1,5}?/
console.log(rex.exec('45684'));

在这里插入图片描述

 小练习

    练习1

      需求

捕获第一个div的完整标签。

      代码

<!-- 我们可以通过贪婪限制符号,来获取标签,这是一种常见的场景。
不加?的话,则.会尽可能获取多的内容,左右<>会匹配最外面两边的尖括号。
加上贪婪限制符之后,则会选择最少的内容并
且达成<>的条件。 -->
let str = '<div style=" color : "red""></div>'

let rex = /<.+?>/

console.log(rex.exec(str));

在这里插入图片描述

    练习2


let rex = /abcd{2}/;
console.log(rex.test('abcddjhgfff'));  true
<!-- 上面题目中,表示的是两个d  也就是abcdd,
而不是abcabc 如果字符串中包含abcdd则返回true -->

  元字符——特殊符号

()

被()括起来的内容,表示一个整体,可以整体括起来进行输出。

<!-- 括起来表示一个整体 所以是匹配两次括号里的内容,也就是需要字符串内包含abcdabcd -->
let rex = /(abcd){2}/

console.log(rex.test('dssdabcdabcd'));  true

除此之外,还会单独捕获括号内的内容,从左边开始的每一个小括号里的内容都是从索引1开始的数组内容,索引0为匹配到的内容

<!-- 索引0为匹配到的结果abcdefg
索引1为左边开始的第一个小括号 ab
索引2为左边第二个小括号cdefg
索引3为左边第三个小括号de -->
let rex = /(ab)(c(de)fg)/
console.log(rex.exec('abcdefghijklmn'));

在这里插入图片描述

(?:)

和()的区别就是,这个只有整体效果,不会捕获括号内的数据变成索引内容

let rex = /(?:ab)(?:c(?:de)fg)/
console.log(rex.exec('abcdefghijklmn'));

在这里插入图片描述

|

表示或者,会匹配满足的一项内容。

let rex = /123|456/;
console.log(rex.exec('212456'));

在这里插入图片描述

[]

表示匹配中括号内的任意一项

let rex = /[abcd]/;
console.log(rex.exec('graedfsab'));

在这里插入图片描述

[^]

表示匹配非中括号内的任意一项

let rex = /[^abcd]/;
console.log(rex.exec('graedfsab'));

在这里插入图片描述

[n-m]

表示n到m之间的内容,n到m之间的内容实际上是之间的ascll码值。

let rex = /[0-9]/;
console.log(rex.exec('g2raedfsab'));

在这里插入图片描述

\num

表示前面的某个括号内的东西,重复出现一遍,/1这个数字1不是指的是出现几次,而是指的是第几个小括号内的结果重复来一遍

let rex = /(abc|def)\d+\1/;
console.log(rex.test('dsabc123abc'));     true
console.log(rex.test('dsabc123def'));     false

  组合形式

[09a-zA-Z_] 等于 \w
[^09a-zA-Z_] 等于 \W
[0-9] 等于 \d
[^0-9] 等于 \D
[ ] 等于 \s
[^ ] 等于 \S
注意:当.放在[]中只代表一个.,相当于加了转义符 

  标识符

i

表示忽略大小写

let rex = /[abcdef]/i;
console.log(rex.test('ABC'));   true

g

表示全局查找,或许应该叫动态查找,跟动态变量一样,下次的查找会遵循上一次查找的位置继续查找,如果查找不到了就返回null,还继续查找的话,会从头开始。对于字符串match方法加了g,则会一次性返回所有匹配内容

let rex = /\d{1}/g
console.log(rex.exec('123'));
console.log(rex.exec('123'));
console.log(rex.exec('123'));
console.log(rex.exec('123'));
console.log(rex.exec('123'));
console.log(rex.exec('123'));
let rex = /es(?=2015|2016)/g
let str = 'es2015es2016es2017'
console.log(str.match(rex));

在这里插入图片描述

y

粘性全局跟g的区别就是粘性全局不能间隔捕获,也就是第一个匹配的内容必须从【0】开始就捕获到,第二个内容必须从第一个内容的结束位开始就捕获到,如果没有捕获到就返回null,下次捕获就从头开始。

let rex = /\d{1}/y
console.log(rex.exec('123'));
console.log(rex.exec('1g2g3'));
console.log(rex.exec('123'));
console.log(rex.exec('12g3'));
console.log(rex.exec('123'));

在这里插入图片描述

 小练习

   练习1

let rex = /^(abc|def){2}$/;
console.log(rex.test('abcabc'));  true
console.log(rex.test('defdef'));  true
console.log(rex.test('abcdef'));  true
console.log(rex.test('defabc'));  true

   练习2

验证一个字母字符串,只能由数字字母下划线组成,6到12位,不能以_开头。

let rex = /^[a-zA-Z0-9]\w{5,11}$/;
console.log(rex.test('ads54s_'));
console.log(rex.test('_ads54s'));
console.log(rex.test('%ads54s'));

    练习3

正则验证数字,验证0-255

思路:把0-255数字分成几类
一位数   \d
两位数   \d{2}
1开头的三位数   1\d{2}
2开头的第二位是0-4的三位数   2[0-4]\d
2开头的第二位是5的第三位为0-4的三位数   2[5]\d

let rex = /^(\d|\d{2}|1\d{2}|2[0-4]\d|25[0-5])$/
修改后
let rex = /^(1?\d{1,2}|2[0-4]\d|25[0-5])$/

console.log(rex.test('0454441')); false
console.log(rex.test('234')); true
console.log(rex.test('123')); true
console.log(rex.test('25622')); false

    练习4

邮箱匹配

邮箱@前的字符为6到10位,不能以下划线开头,只能由数字字母下划线组成,只能是qq 网易163邮箱,后缀只能是.com或.cn

let rex = /^[0-9a-zA-Z]\w{5,9}@(qq|163)(.com|.cn)$/;
console.log(rex.test('22175451@163.com')); true

正则的预查

  正向预查

   正向肯定

(?=)

捕获某个内容的时候,可以增添条件,比如后面需要连接什么,例如,我想吃泡面,吃老坛酸菜的,泡面是内容,老坛酸菜是条件

<!-- 匹配es2015或者es2016,这种符合要求的,
匹配到了之后,得到es。也就是说   我要拿到es,但是我要拿到es2015或者2016里面的es -->
let rex = /es(?=2015|2016)/;
console.log(rex.exec('es2015'));
console.log(rex.exec('es2016'));
console.log(rex.exec('es2017'));

在这里插入图片描述

   正向否定

(?!)

捕获某个内容的时候,可以增添条件,比如后面不需要连接什么,例如,我想吃泡面,不吃老坛酸菜的,泡面是内容,不吃老坛酸菜是条件

let rex = /es(?!2015|2016)/;
console.log(rex.exec('es2015'));
console.log(rex.exec('es2016'));
console.log(rex.exec('es2017'));

在这里插入图片描述

  负向预查

   负向肯定

跟正向肯定一样,区别就是,负向的肯定的条件在前面。

(?<=)

let rex = /(?<!2015|2016)es/;
console.log(rex.exec('2015es'));
console.log(rex.exec('2016es'));
console.log(rex.exec('2017es'));

在这里插入图片描述

let rex = /(?<=2015|2016)es/;
console.log(rex.exec('2015es'));
console.log(rex.exec('2016es'));
console.log(rex.exec('2017es'));

在这里插入图片描述

   负向否定

跟正向否定一样,区别就是,负向的否定的条件在前面。

 let rex = /(?<!2015|2016)es/;
 console.log(rex.exec('2015es'));
 console.log(rex.exec('2016es'));
 console.log(rex.exec('2017es'));

在这里插入图片描述

  字符串与正则合作的几个方法

    search()

这个方法就是查找匹配对象的索引位置,只返回索引位置。

let rex = /a/
let str = 'dsa';
console.log(str.search(rex));    2

    replace()

使用正则表达式替换字符串,没有\g的时候只会替换第一个匹配的,有\g则替换掉所有匹配符合的内容。

let str = '11111'
console.log(str.replace(/1/g, 'a'));
console.log(str.replace(/1/g, function (data) {
    return Number(data) + 1;
}));

在这里插入图片描述

    match()

跟exec类似,区别就是正则表达式为g的时候会匹配所有符合的内容

let rex = /es(?=2015|2016)/g
let str = 'es2015es2016es2017'
console.log(str.match(rex));

在这里插入图片描述

在这里插入图片描述

    search()

这个方法就是查找匹配对象的索引位置,只返回索引位置。

let rex = /a/
let str = 'dsa';
console.log(str.search(rex));    2

    replace()

使用正则表达式替换字符串,没有\g的时候只会替换第一个匹配的,有\g则替换掉所有匹配符合的内容。

let str = '11111'
console.log(str.replace(/1/g, 'a'));
console.log(str.replace(/1/g, function (data) {
    return Number(data) + 1;
}));

    match()

跟exec类似,区别就是正则表达式为g的时候会匹配所有符合的内容

let rex = /es(?=2015|2016)/g
let str = 'es2015es2016es2017'
console.log(str.match(rex));

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。