前言
曾经我一度对正则表达式有种恐惧和厌恶感,为啥?因为总感觉这玩意很难,很枯燥,看到别人写出贼牛逼的正则,我想啥时候我能像他们一样优秀。直到我看到了这三个知识点。。。
只需要花10分钟时间,你可以收获
正则表达式中的位置匹配原理与知识
正则表达式中的字符串匹配原理与知识
正则表达式中的括号的妙用
14个常见正则表达式解析帮助理解知识点
相信我,看完这篇文章,对于工作中90%以上的正则问题你都能找到解决思路和方案。
相信我,看完这篇文章,对于工作中90%以上的正则问题你都能找到解决思路和方案。
相信我,看完这篇文章,对于工作中90%以上的正则问题你都能找到解决思路和方案。
默念三声
正则表达式是匹配模式,要么匹配字符,要么匹配位置
正则表达式是匹配模式,要么匹配字符,要么匹配位置
正则表达式是匹配模式,要么匹配字符,要么匹配位置
1.搞懂位置能干啥?
题目1:数字的千分位分割法
将123456789转化为123,456,789
题目2:手机号3-4-4分割
将手机号18379836654转化为183-7983-6654
题目3:验证密码的合法性
密码长度是6-12位,由数字、小写字符和大写字母组成,但必须至少包括2种字符
这些题时常出现在面试中,日常业务也少不了它的身影。搞懂位置,不仅能搞定面试,业务你也将写的飞起
啥是位置?
正则表达式是匹配模式,要么匹配字符,要么匹配位置。那什么是位置呢?
如下图箭头所指,位置可以理解为相邻字符之间的位置。
咱们可以和空字符串进行类比, 字符的首尾、间隙都可以用空字符串进行连接。
'hello' === '' + 'h' + '' + 'e' + '' + 'l' + '' + 'l' + '' + 'o' + '' // true
有哪些位置?
正则中常用来表示位置的符号主要有:
^、$、b、B、?=p、(?!p)、(?^
脱字符,匹配行的开头
例如要在hello的开头塞一个笑脸( )怎么搞,这个肯定难不倒你
let string = 'hello'
console.log(string.replace(/^/, '')) // hello
$
美元符号,匹配行的结尾
同理想在hello的结尾塞一个笑脸( )呢?
let string = 'hello'
console.log(string.replace(/$/, '')) // hello
这两个表示首尾位置的符号,相信大家一定都很熟悉。
b
单词的边界,具体讲有三点规则。
① w和W之间的位置
② ^与w之间的位置
③ w与 $ 之间的位置
比如藏在你们电脑上学习教程文件夹中的某一集种子长这样xxx_love_study_1.mp4,想要把他变成❤️xxx_love_study_1❤️.❤️mp4❤️怎么搞呢?
其实只需要执行一行代码就行
'xxx_love_study_1.mp4'.replace(/b/g, '❤️') // ❤️xxx_love_study_1❤️.❤️mp4❤️
画图理解就是
B
非单词的边界,也就是b反着来的意思,它的规则如下:
① w与w之间的位置
② W与W之间的位置
③^与W之间的位置
④W与 $ 之间的位置
同样还是用学习教程文件夹中的种子,稍稍改造一下,当执行这行代码之后,会输出啥?
'[[xxx_love_study_1.mp4]]'.replace(/B/g, '❤️')
….
没错,满满的都是爱啊!!!,都快看不清名字了。
❤️[❤️[x❤️x❤️x❤️_❤️l❤️o❤️v❤️e❤️_❤️s❤️t❤️u❤️d❤️y❤️_❤️1.m❤️p❤️4]❤️]❤️
画图解释如下
(?=p)
符合p子模式前面的那个位置。换句话说是,有一个位置,紧跟其后需要满足p子模式。也有一个学名叫正向先行断言。
还是这个例子xxx_love_study_1.mp4,要在xxx(xxx可以指代任何你喜欢的那个TA)前面塞一个❤️,怎么写呢?
是这样吗? 不是的,这样会导致你的xxx都不见了,那还要❤️做什么呢?
'xxx_love_study_1.mp4'.replace('xxx', '❤️') // ❤️_love_study_1.mp4
利用(?=p)就可以很方便这这件事(可以想想和上面有什么不同?)
'xxx_love_study_1.mp4'.replace(/(?=xxx)/g, '❤️') // ❤️xxx_love_study_1.mp4
画图理解
(?!p)
(?=p)反过来的意思,可以理解为(?=p)匹配到的位置之外的位置都是属于(?!p)的,它也有一个学名叫负向先行断言。
'xxx_love_study_1.mp4'.replace(/(?!xxx)/g, '❤️')
// (?=xxx)的输出
❤️xxx_love_study_1.mp4
// (?!xxx)的输出
x❤️x❤️x❤️_❤️l❤️o❤️v❤️e❤️_❤️s❤️t❤️u❤️d❤️y❤️_❤️1❤️.❤️m❤️p❤️4❤️
仔细对比一下,是不是除了(?=xxx)匹配到最前面那个位置,其他位置都是(?!xxx)匹配到的啦。
(?栗子详解
学习完位置相关的知识,我们来做一下开头的几个题目试试
题目1:数字的千分位分割法
将123456789转化为123,456,789
观察题目的规律就是从后往前,每三个数字前加一个逗号,(需要注意的是开头不需要加逗号,)。是不是很符合 (?=p)的规律呢?p可以表示每三个数字html转义字符,要添加的逗号所处的位置正好是(?=p)匹配出来的位置。
第一步,尝试先把后面第一个逗号弄出来
let price = '123456789'
let priceReg = /(?=d{3}$)/
console.log(price.replace(priceReg, ',')) // 123456,789
第二步,把所有的逗号都弄出来
要把所有的逗号都弄出来,主要要解决的问题是怎么表示三个数字一组,也就是3的倍数。我们知道正则中括号可以把一个p模式变成一个小整体,所以利用括号的性质,可以这样写
let price = '123456789'
let priceReg = /(?=(d{3})+$)/g
console.log(price.replace(priceReg, ',')) // ,123,456,789
第三步,去掉首位的逗号,
上面已经基本上实现需求了,但是还不够,首位会出现,那怎么把首位的逗号去除呢?想想前面是不是有一个知识正好满足这个场景? 没错(?!p),就是他了,两者结合就是从后往前每三个数字的位置前添加逗号html转义字符,但是这个位置不能是^首位。
let price = '123456789'
let priceReg = /(?!^)(?=(d{3})+$)/g
console.log(price.replace(priceReg, ',')) // 123,456,789
题目2:手机号3-4-4分割
将手机号18379836654转化为183-7983-6654
有了上面数字的千分位分割法,做这个题相信会简单很多,也就是从后往前找到这样的位置:
每四个数字前的位置,并把这个位置替换为-
let mobile = '18379836654'
let mobileReg = /(?=(d{4})+$)/g
console.log(mobile.replace(mobileReg, '-')) // 183-7983-6654
题目3:手机号3-4-4分割扩展
将手机号11位以内的数字转化为3-4-4格式
回想一下这样的场景,有一个表单需要收集用户的手机号,用户是一个个数字输入的,我们需要在用户输入11位手机号的过程中把其转化为3-3-4格式。即
123 => 123
1234 => 123-4
12345 => 123-45
123456 => 123-456
1234567 => 123-4567
12345678 => 123-4567-8
123456789 => 123-4567-89
12345678911 => 123-4567-8911
这样用(?=p)就不太合适了,例如1234就会变成-1234。 想想前面的知识点有适合处理这种场景的吗?是的(?
限时特惠:本站每日持续更新海量设计资源,一年会员只需29.9元,全站资源免费下载
站长微信:ziyuanshu688