JavaScript正则表达式学习笔记

RegExp正则笔记地址(高颜值求收藏)

RegExp

正则表达式(RegExp)是一种匹配字符串书写格式的专用表达式,由于它体积小,执行效率高,正则表达式也被集成到很多编程语言中,在C、C++、Java、JavaScript都有应用

!> 本教程是以JavaScript为基础讲解正则表达式,若使用其他编程语言,可以选择性的参考本教程

JSAPI

在学习正则表达式之前,我们首先要了解JavaScript对正则表达式的支持

test()

用途

用来验证字符串是否匹配正则表达式,匹配则返回true,不匹配则返回false

语法

RegExp.test(String)//返回true/false

案例

// 该正则表达式的含义是匹配5个数字
var reg=/\d{5}/
var str="12345"
console.log(reg.test(str))// true

match()

用途

用来返回字符串匹配正则表达式的结果

语法

String.match(RegExp)//返回一个匹配结果数组或匹配详情

案例

// 该正则表达式表示匹配所有的数字
var reg=/\d/g
var str="abc123g3b445gbh331"
console.log(str.match(reg))// [1,2,3,3,4,4,5,3,3,1]

!> 注意:match()和test()不同,match前面是字符串,后面是正则表达式

replace()

用途

用来替换符合正则表达式的文本

语法

String.replace(RegExp,String)//返回一个替换后的字符串

案例

// 正则表达式含义:匹配所有数字
var reg=/\d/g
var str="abc123tyu678"
// 将所有的数字替换成*
str=str.replace(reg,'*')
console.log(str)// abc***tyu***

!> 注意:replace方法不会修改字符串本身,而是返回一个替换结果

search()

用途

用来查找匹配结果的位置

语法

String.search(RegExp)//返回索引值

案例

// 正则表达式含义:匹配所有数字
var reg=/\d/
var str="abcf3ght"
console.log(str.search(reg))// 4

RegExp基础

通过上面内容的学习,我们了解了JS对于正则表达式的支持,那么现在就正式学习正则表达式吧。

创建正则表达式

创建正则表达式我们有两个选择:

  • 使用//双斜杠创建
  • 使用RegExp对象创建
双斜杠创建
// \d代表一个数字,这个正则表达式是匹配数字的意思
var reg=/\d/
RegExp
// 为什么要写两个\\,这是因为\在字符串中有转义含义,\\相当于一个\,%%相当于%
var reg=new RegExp("\\d")

字符串

字符串其实就是最简单的正则表达式,比如我们想要匹配一个人的名字,我们就可以把这个人的名字作为正则表达式

模糊匹配

模糊匹配指的是,只要包含这个内容就可以,不需要完全符合

// 匹配张三
var reg=/张三/
var name1="张三"
var name2="李四"
var str="我叫张三,我今年18岁了"
// test用于测试字符串是否符合正则表达式
console.log(reg.test(name1),reg.test(name2),reg.test(str))// true false true

!> 看起来可以实现匹配姓名的功能,不过其实它是有问题的,因为他是模糊匹配,不精确

// 假如有个人叫张三丰,那么匹配结果会怎么样呢
var reg=/张三/
var name="张三丰"
console.log(reg.test(name))// true

这是为什么呢?原因是模糊匹配只要匹配到了就可以,由于张三丰包含张三,所以返回true

看起来模糊匹配并不能解决匹配姓名的问题,下面就要有请精准匹配了

精准匹配

精准匹配要求的是匹配内容必须完全符合,包含关系不可以,必须全等

语法:在正则表达式的开头加上^,结尾加上$

var reg=/^张三$/
console.log(reg.test("张三"),reg.test("张三丰"))// true false

使用了精准匹配过后,我们就可以匹配到精确的结果了

匹配开头

我们有些时候想匹配以xxx开头的句子,那我们需要怎么写呢?

语法:在正则表达式的开头加上^

// 匹配以猫开头的正则表达式
var reg=/^猫/
var str1="猫是一种哺乳动物,它很可爱"
var str2="我喜欢猫,我养了很多只"
console.log(reg.test(str1),reg.test(str2))// true false

!> ^的含义是匹配开头

匹配结尾

我们有些时候想匹配以xxx结尾的字符串,那我们怎么写呢?

语法:在正则表达式的结尾加上$

// 匹配以txt结尾的字符串
var reg=/txt$/
var str="hello.txt"
var str1="txt.ppt"
var str2="helloworldtxt"
console.log(reg.test(str),reg.test(str1),reg.test(str2))// true false true

!> $的含义是匹配结尾

你可能会想为什么我们不写.txt作为正则表达式呢,因为.在正则表达式中有特殊含义,它表示任意一个字符

如果我们想使用.让它只是表示点的含义,而不是任意一个字符,就需要对它进行转义:使用\.

特殊符号表示含义
.任意一个字符
\.表示小数点.

所以我们可以这样修改我们的正则表达式

// 匹配.txt文件
var reg=/\.txt/ //   \.表示.   .表示任意一个字符
var str="hello.txt"
var str1="txt.ppt"
var str2="helloworldtxt"
console.log(reg.test(str),reg.test(str1),reg.test(str2))// true false false

!> 在正则表达式中特殊字符的转义都是使用\加那个字符

匹配模式

在正则表达式中,我们有四种匹配模式

  • 单一匹配(正则默认的匹配模式)
  • 全局匹配(/g)
  • 忽略英文大小写匹配(/i)
  • 全局+忽略英文大小写匹配(/gi)
单一匹配

局部匹配指的是我们只匹配第一个出现的结果,匹配到了就不往下匹配了

// 举个例子:我们需要替换小明,把小明替换为小红
var str="小明是一个好孩子,小明成绩优异,小明是班长"
// 匹配小明
var reg=/小明/
// 使用JSAPI=>replace进行替换
console.log(str.replace(reg,"小红"))
// 结果:小红是一个好孩子,小明成绩优异,小明是班长

!> 总结:单一匹配只匹配第一个出现的结果

全局匹配

全局匹配指的是我们要查找全部的匹配结果,而不是匹配到了一个就不往下匹配了

语法:使用/g,g是英文global的缩写

// 举个例子:我们需要替换小明,把小明替换为小红
var str="小明是一个好孩子,小明成绩优异,小明是班长"
// 使用g启动全局匹配
var reg=/小明/g
// 使用JSAPI=>replace进行替换
console.log(str.replace(reg,"小红"))
// 结果:小红是一个好孩子,小红成绩优异,小红是班长

!> 总结:全局匹配匹配所有符合条件的结果

忽略大小写匹配
var reg=/a/i
var str="a"
var str1="A"
console.log(reg.test(str),reg.test(str1))

!> 忽略大小写匹配,会忽略大小写

元字符

元字符是一个字符的集合,它表示集合内的任何一个字符。

格式

[字符集]

例子

匹配一个数字:[0-9]或[0123456789]

匹配一个小写英文:[a-z]或[abcdefghijklmnopqrstuvwxyz]

匹配一个大写英文:[A-Z]或[ABCDEFGHIJKLMNOPQRSTUVWXYZ]

匹配一个英文字符的话:[a-zA-Z]或[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]

!> 如果是ASCLL码相邻的字符,可以用-简写

// 匹配一个数字
var reg=/[0-9]/
var num="1"
var num1="2"
var charset="a"
var format="^"
console.log(reg.test(num),reg.test(num1),reg.test(charset),reg.test(format))// true true false false

!> 元字符只能代表这个特征范围内的一个字符,如果想要匹配这个范围内的多个字符,就需要引入量词

量词

量词用来修饰元字符,用来限制元字符出现的频率

格式

[字符集]{min,max} 表示元字符最少出现min次,最多max次

[字符集]{min,} 表示元字符最少出现min次,最多没有限制

[字符集]{count},表示元字符必须出现count次

例子

匹配至少3个数字:[0-9]{3,}

匹配2-5个数字:[0-9]{2,5}

// 匹配手机电话号码 手机电话号码特征是11位数字
// 开启精准匹配,防止14位包含13位匹配的情况
var reg=/^[0-9]{11}$/
var phone="13253678799"
var str="123456789"
console.log(reg.test(phone),reg.test(str))// true false

与或非

正则表达式也会有与或非的基本逻辑关系

与表示既要满足这个也要满足那个,与是正则表达式默认的逻辑模式

比如:我想匹配数字和英文字母(包括大小写)

/[0-9][a-z][A-Z]/

!> 与的话就是直接串起来就行

或表示这也行,那个也行

比如:我想匹配音频文件,音频格式的话后缀.mp3可以,.ogg可以,.wav也行

/\.mp3|\.ogg|\.wav$/

!> 或的话用|表示

非的话表示除了这个之外都行,在正则表达式中非只能在元字符中使用

// 表示除了数字以外都行
/[^0-9]/
// 表示除了英文都行
/[^a-zA-Z]/

!> 在//双斜杠中的含义是匹配开头的意思,在[ ]元字符中的含义是非

特殊元字符

某些特殊的元字符是可以简写的

可以简写的元字符
原始写法简写含义
[0-9]\d匹配一个数字
[^0-9]\D匹配除了数字任何一个字符
[0-9a-zA-Z]\w匹配英文和数字中任何一个字符
[^0-9a-zA-Z]\W匹配除了英文和数字中任何一个字符
[\r\n\f\t]\s匹配换行符、空格等空白字符
[^\r\n\f\t]\S匹配非空白字符

\w通常被认为匹配文本 因为在使用英文国家里数字 英文就是文本

案例

匹配至少出现5个数字,开头必须是英文

/^[a-zA-Z]{1,}\d{5,}/

特殊量词

某些特殊的量词也是可以简写的

可以简写的量词
原始写法简写含义
{0,1}?出现频率0或1次(可有可无)
{0,}*不出现或者出现任意次
{1,}+至少出现一次
案例

匹配整数或小数

/^-?\d+\.?(\d+)?$/

这个正则表达式就是表示的整数或者小数,加括号是对这个整体进行量词修饰

var reg=/^-?\d+\.?(\d+)?$/
var num="12"
var dic="3.14"
var str="3.14abd"
console.log(reg.test(num))
console.log(reg.test(dic))
console.log(reg.test(str))

!> 正则表达式和因式分解一样,可以进行提取公因式

// 匹配整数和小数,提取公因式版
var reg=/^-?\d+(\.\d+)?$/
var num="12"
var dic="3.14"
var str="3.14abd"
console.log(reg.test(num))
console.log(reg.test(dic))
console.log(reg.test(str))

因式分解前

/^-?\d+\.?(\d+)?$/

因式分解后

/^-?\d+(\.\d+)?$/

!> 因式分解可以可以简化正则表达式

正则表达式分组

正则表达式可以进行分组,这样我们可以用$1、$2…来获取它们的匹配值

语法

(正则表达式1)(正则表达式2)…

使用括号包裹

案例
var reg=/(\d+)([a-z]+)([A-Z]+)/
var str="123abcABCDEF"
reg.test(str)
// 分别获取匹配结果的全部匹配结果、第一组、第二组、第三组的匹配结果
console.log(str.match(reg),str.match(reg)[1],str.match(reg)[2],str.match(reg)[3])
// 我们也可以利用RegExp直接获取它们的分组匹配结果
console.log(RegExp.$1,RegExp.$2,RegExp.$3)
// 输出结果为 123 abc ABCDEF

!> 只要使用了JSAPI,RegExp就会被激活,上面案例使用了test,激活了RegExp

未被激活的RegExp里面内容为undefined ex:RegExp.$1->undefined

上面我们书写了匹配整数或小数的正则表达式

/^-?\d+(\.\d+)?$/

由于这个正则表达式有括号,是正则分组的语法,于是我们便可以轻松的获取匹配结果的小数部分

var reg=/^-?\d+(\.\d+)?$/
reg.test("3.14")
console.log(RegExp.$1)// .14

RegExp提高

通过RegExp的基础学习我们了解到了,正则表达式的一些基础特点。那么下面我们来进一步深入学习正则表达式

匹配中文

现在有一个需求,有一串文字,我们要把所有的中文查找出来,然后翻译成英文,之后替换原来的中文,使得通篇都是英文。来保证英国人可以看懂中文网站

这就是谷歌翻译做的事情,现在我们要实现它。当然翻译需要翻译接口,这里可以自行百度,但是这可能要收费,不过网上也有很多破解方法。

// 对于匹配中文的话我们只能使用unicode编码进行匹配
/[\u4e00-\u9fa5]/
// 这个unicode范围匹配是汉字

替换汉字内容(模拟谷歌翻译)

var reg=/[\u4e00-\u9fa5]/g
var str="我是postman,大家好"
console.log(str.replace(reg,"ki "))

边界匹配

现在我有一个需求,对于字符串“abcdefg”,我想给它们的缝隙添加一个+号,也就是变成+a+b+c+d+e+f+g+

这个就是属于边界匹配的内容了,对于正则表达式而言,我们不仅可以匹配原文内容,原文之间的分隔我们也可以进行操作

原始写法简写含义
()()\b表示空位

!> \b表示字符串的边界

// 匹配空位 开器全局模式/g
var reg=/()()/g
// 字符串abcdefg
var str="abcdefg"
console.log(str.replace(reg,"+"))//+a+b+c+d+e+f+g+
var str1="abc 你好 你a好b"
console.log(str1.replace(reg,"-"))//-a-b-c- -你-好- -你-a-好-b-

!> 边界其实就是缝隙

零宽断言

在学习零宽断言之前,我们请看一个例子

我们现在有个字符串:张家屯的小王和苏家屯的小王是好朋友

现在我想匹配张家屯的小王,不想匹配苏家屯的小王,怎么办?

这个时候我们就需要使用零宽断言

// ?<=张家屯的,表示前面必须是张家屯
var reg=/(?<=张家屯的)小王/g
var str="张家屯的小王和苏家屯的小王是好朋友"
var res=str.replace(reg,"小李")
console.log(res)

!> (?<=)是零宽断言,它可以修饰匹配对象,表示小王前面必须是张家屯的

零宽

零宽的意思是它不占据匹配结果

/(?<=张家屯的)小王/g匹配的其实还是小王,没有张家屯的

var reg=/(?<=张家屯的)小王/g
var str="张家屯的小王"
var res=str.match(reg)
console.log(res)// ["小王"]

但是/(张家屯的)(小王)/g匹配的却是包含张家屯的,是占据匹配宽度的

var reg=/(张家屯的)(小王)/g
var str="张家屯的小王"
var res=str.match(reg)
console.log(res)// ["张家屯的小王"]

!> 零宽是不占据匹配结果的,正常的分组是占据匹配结果的

断言

断言是用来修饰匹配内容的,要求匹配内容必须符合xxx条件。

就像/(?<=张家屯的)小王/g一样,不是所有的小王都行,必须前面是张家屯的才行,这就是断言

前置断言

修饰语在前面的断言叫前置断言

// 匹配猫,且前面的修饰必须是聪明的
var reg=/(?<=聪明的)小猫/
var str="可爱的小猫,聪明的小猫,懒散的小猫"
console.log(str.replace(reg,"小猫咪咪"))// 可爱的小猫,聪明的小猫咪咪,懒散的小猫
后置断言

修饰语在后面的断言叫后置断言

// 匹配猫,且后面的修饰必须是很开心
var reg=/小猫(?=很开心)/
var str="我养了一致小猫,小猫会玩耍,小猫很开心"
console.log(str.replace(reg,"小猫咪咪"))//我养了一致小猫,小猫咪咪会玩耍,小猫很开心

!> 断言可以理解为形容词,是对匹配内容的修饰

零宽断言

零宽断言是指既不占据匹配结果,又能起到修饰名词作用的断言

常见的零宽断言如下

零宽断言断言类型备注
?<=前置断言表示前面必须是xxx
?<!前置断言表示前面不能是xxx
?=后置断言表示后面必须是xxx
?!后置断言表示后面不能是xxx
?!^前置断言忽略首位的匹配结果
?!$后置断言忽略末位的匹配结果
案例
匹配中间部分的数字
var str="123456"
var reg=/(?!^)\d(?!$)/g
console.log(str.match(reg))// 2345
匹配属性值

现在我想获取下面这个标签的class属性值

<div class="navBar"></div>

使用正则

var reg=/(?<=class\=\").+(?=\")/g
var html=`<div class="navBar"></div>`
console.log(html.match(reg))

我们使用\= 是为了转义=;使用\“是为了转义”;\w+是指很多个文字,.指的是任意一个字符(不包括一些特殊字符)

贪婪匹配

比如现在我想筛选下面h1标签内的文字

<h1>标题一</h1>文本<h2>标题二</h2>

我们可能要这样写正则表达式

var reg=/(?<=\>).*(?=<)/g
var str=`<h1>标题一</h1>文本<h2>标题二</h2>`
console.log(str.match(reg))//标题一</h1>文本<h2>标题二

从匹配结果我们可以看到,他就是特别的贪婪,一直匹配到底了

那么如何解决这个问题呢?
我们可以使用量词巧妙解决:

// 加一个?,就解决了。?是可有可无的意思
var reg=/(?<=\>).*?(?=<)/g
var str=`<h1>标题一</h1>文本<h2>标题二</h2>`
console.log(str.match(reg))// ["标题一","文本","标题二"]

!> .*?这个组合被称之为非贪婪匹配,可以使得正则不再贪婪,是见好就收,而不是一贪到底

难点挑战

金钱分隔

现在有一个比较大的数字:1234567,你需要把它处理成1,234,567

也就是说每三位为一个分隔,从低位到高位进行分隔

function formatPrice(price){
    var reg=/(?!^)(?=(\d{3})+\b)/g
    return price.toString().replace(reg,",")
}
console.log(formatPrice(1234567)) //1,234,567

\b是边界,指的是最右边的边界

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值