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

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

体验正则表达式的能力

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

  普通代码

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'));

      捕获到

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));


目录
相关文章
|
3月前
|
设计模式 算法 安全
2023下半年软件设计师 关于我用了半个月过了软件设计师这件事
这篇文章分享了作者在仅用半个月的业余时间备考并通过2023下半年软件设计师考试的经历,包括备考策略、所用资料和个人建议,同时提供了相关备考资料的获取方式。
|
4月前
|
Python
京东技术团队撰写的整整986页《漫画学Python》到底有什么魅力?
这是一本Python入门书。无论您是想学习编程的小学生,还是想参加计算机竞赛的中学生,抑或是计算机相关专业的大学生,甚至是正在从事软件开发的职场人,本书都适合您阅读和学习。但您若想更深入地学习Python并进行深层次应用,则需要选择其他相关图书。
|
6月前
开学之际被Turkey问候,只能祭出正则大法
开学之际被Turkey问候,只能祭出正则大法
24 0
|
6月前
|
开发者
作为微信小游戏开发者,这份白皮书不看可太吃亏了!
作为微信小游戏开发者,这份白皮书不看可太吃亏了!
185 1
连夜整理七个开源项目:练手、毕设、接私活都不愁了
项目一:cloud-platform 学习重点: 服务鉴权中心 用户间鉴权 服务之间鉴权 springcloud组件大回顾
|
开发框架 JSON 小程序
开源分享|如何解锁小程序开发?这份攻略请收好!
本期我们整理了一些用于小程序开发的开源项目,快来围观~
247 0
|
程序员 Android开发 iOS开发
程序员五一修图小贴士
程序员五一修图小贴士
155 0
程序员五一修图小贴士
|
Python Windows
【教你用python挣零花钱】自动化简历内推,学弟直呼牛逼!!
【教你用python挣零花钱】自动化简历内推,学弟直呼牛逼!!
【教你用python挣零花钱】自动化简历内推,学弟直呼牛逼!!
|
移动开发 前端开发 Java
令我室友大为震惊!手把手教我室友撕web前端基础知识,上手小项目广告推广软文页面。
令我室友大为震惊!手把手教我室友撕web前端基础知识,上手小项目广告推广软文页面。
167 0
令我室友大为震惊!手把手教我室友撕web前端基础知识,上手小项目广告推广软文页面。
|
供应链 小程序 安全
社区团购讲堂之敲黑板、划重点!社区团购哪些是考点?
任何一个行业要想持续发展,就要不断的汲取新事物的营养,跟上趋势的节奏,才能在激烈的市场竞争中脱颖而出,屹立不倒!社区团购之所以被资本市场青睐,其根本原因在于,社区团购符合了当下消费者的“潜在核心需求”。