头图

你能看懂的正则表达式(JavaScript语言表述)

不羁的风
本人是一枚前端小喽啰,在工作中常用到正则表达式,于是抽空系统学习了一下正则表达式基础。今天笔者就把所学内容分享给大家,笔者将首先展示一些小例子,带领大家逐步理解正则表达式,然后在这些小例子的基础上,实现一个可以匹配邮箱地址的正则(本文所列案例皆可在浏览器控制台执行)。

直奔主题

1. 最简单的正则:匹配特定字符串
let reg = new RegExp("a")
reg.test("a")
//结果为true
reg.test("b")
//结果为false

这个例子简单直接,我们使用RegExp构造器构造一个正则表达式对象,这个正则的目标就是匹配字符串中"a",包含返回true,不包含返回false。

2. 正则表达式中的匹配模式
声明正则表达式对象时,可以给正则表表达式传递第二个参数即:匹配模式。匹配模式有三个类型:
修饰符描述
i不区分大小写匹配
g全局匹配
m多行匹配。

这里,我们创建一个不区分大小写的正则表达式:

//注意,匹配模式的参数也是String类型
let reg = new RegExp("a","i")
reg.test("A")
//结果为true
reg.test("b")
//结果为false

当然,在JavaScript中也可以通过字面量方式创建正则表达式,这种方式创建的正则表达式与采用RegExp构造的对象是一样的,类型同样是Object。

//构造器方式
let reg = new RegExp("a","i")
//字面量方式
let reg = /a/i
3. 检测一个字符串中是否有"a"或"b"(大小写不敏感)
let reg = /a|b/i
reg.test("a")
//true
reg.test("b")
//true
reg.test("riku")
//false

定义一个正则表达式时,如果将某些字符放到[]内,则[]内的字符是或的关系,即只要包含任意一个即为true。

4. 匹配任意字母
let reg = /[A-z]/
reg.test("douban")
//true
reg.test("taoBao")
//true
reg.test("123")
//false

这个正则用来匹配大写A到小写z之间的所有字符,因为大写字母的ASCII码比小写字母的ASCII码要小,所以A-z表示所有字母,再放到[]中表示对任意大小写字母的匹配,所以这里我们不再需要名称为i的修饰符来表示不区分大小写。

5. 匹配abc、bbc、cbc中任意一个字符串
let reg = /[abc]bc/
reg.test("abc")
//true
reg.test("bbc")
//true
reg.test("cbc")
//true
reg.test("1bc")
//false
6. 匹配abc之外的字符串
let reg = /[^abc]/
reg.test("ab")
//false
reg.test("abx")
//true 因为包含了除abc之外的字符x
let reg = /[^0-9]/
//该正则可以匹配任何非数字的字符,比较常用!

在方括号之前加上^符号,表示匹配任意不在方括号之间的字符。

与正则相关的字符串方法

与字符串相关的正则方法一共有四个,如下表所列:

方法名具体作用
search检索与正则表达式相匹配的值
match找到一个或多个正则表达式的匹配
replace替换与正则表达式匹配的子串
split把字符串分割为字符串数组

我们先从split说起:

1. 根据任意数字拆分字符串
let str = "a1b2c3d4e5f6g"
let arr = str.split(/[0-9]/)
console.log(arr)
// 结果为["a", "b", "c", "d", "e", "f", "g"]

字符串的split方法可以根据指定规则拆分字符串,这里我们需要注意的是,即使没有执行全局匹配,split依旧会对整个字符串执行拆分操作

字符串的search方法可以搜索字符串中是否含有指定内容,类似于str.indexOf()方法,如果搜索到则返回第一个匹配到的索引,否则返回-1,对于search,即使指定了全局匹配,返回的也只有第一个匹配到的结果,即search不能全局匹配

2. 搜索一个字符串中的user1,user2,user3
let str = "userlist :user1 ,user2,user3"
console.log(str.search(/user[123]/))
// 结果为10即第一个匹配到的user1的索引值

字符串的match方法,可以根据正则表达式的匹配结果,从一个字符串中提取一个字符串数组。
默认情况下,match方法只会匹配第一个结果,找到后便停止继续向后检索
如果想让match方法进行全局匹配,我们只需加上之前讲的/g修饰符,也可以添加/i修饰符执行大小写不敏感匹配。

3. 提取一个字符串中所有的数字
let str="1a2b3c4d5e6f"
let arr = str.match(/[0-9]/g)
//arr的打印结果为["1", "2", "3", "4", "5", "6"]

str.replace()可以将字符串中匹配到的内容替换为新的内容。replace包含两个参数:
1、被替换的内容(可以是正则表达式)
2、新的内容,可以是一个字符串或者是回调函数,回调函数可以操作匹配到的每一项的内容。

4. 将字符串中小写单词首字母改成大写
let str = "abc bbc cbc"
let reg = /\b\w+\b/g
let result = str.replace(reg, (word) => {
  return word.substring(0, 1).toLocaleUpperCase() + word.substring(1)
})
console.log(result);
在正则表达式中,可以通过量词设定字符出现的次数,但量词只对他前面那一个字符生效,如果我们希望量词对前面几个字符生效,我们可以用括号包起来,如:(ab){3,5} 表示ab出现3-5次,如果省略5,则表示出现3次货3次以上。

常用量词如下表所示:

量词具体作用
{n}检索与正则表达式相匹配的值
{m,n}找到一个或多个正则表达式的匹配
{m,}替换与正则表达式匹配的子串
+至少出现一次,相当于{1,}
*0次或1次或多次,相当于{0,}
?0次或一次,相当于{0,1}
5. 判断一个字符串是否为合法的手机号
let phoneReg = /^1[3-9][0-9]{9}$/
phoengReg.test('13123456789')
//结果为true,我们这里的验证规则时:以1开头,第二位是3-9之间任意数字,  
//剩下9位是任意数字,因此总位数为11位  
//开始的^符号表示开始,最后的$符号表示字符串结束。
6. 去除一个字符串开头和结尾的所有空格
let str  = "   hello   world    "
let strReg = /^\s*|\s*$/g
str = str.replace(strReg,"")
//执行结果为:"hello   world",这里需要指定全局匹配,否则只会匹配前面的空格。

这里,笔者还想介绍一下元字符的概念,就是我们上面一个案例中用到的\s他表示的是任意空格,在正则表达式中常用的元字符如下表所示:

元字符具体含义
\w任意字母、数字、下划线[A-z0-9_]
\W除了字母、数字、下划线[^A-z0-9_]
\d任意数字[0-9]
\D除了数字[^0-9]
\s空格
\S除了空格
\b单词边界
\B除了单词边界

匹配邮箱的正则

正常来说,一个邮箱地址由一下几个部分构成
我们以test.zhou@test.com.cn为例,将邮箱拆分成以下几个部分:
①test    ②.zhou    ③@   ④test  ⑤.com  ⑥.cn对应的匹配规则如下:

任意长度字符串:
\w{3,}
"."或者"_"+任意长度字符串(可选):
((\.|\_)\w+)*
"@"符号
@
任意长度字母数字:
[A-z0-9]+
"."+长度为2-6的字符串:
\.[A-z]{2-6}
"."+长度为2-5的字符串(可选):
\.[A-z]{2-5}

最后我们把刚才分析的6个部分整合到一起,就得到了我们想要的对邮箱进行校验的正则表达式:

let emailReg = /\w{3,}((\.|\_)\w+)*@[A-z0-9]+\.[A-z]{2,6}(\.[A-z]{2,5})*/
emailReg.test("test@test.com.cn") //true
emailReg.test("test.liu@test.test") //true

总结

本文首先从最简单的字符串匹配开始,介绍了如何在JavaScript中使用正则表达式匹配目标对象,然后介绍了正则表达式的匹配模式,接着又介绍了字符串与正则结合使用的四个方法:searchmatchreplacesplit,最后又综合运用正则表达式基础知识,实现了一个邮箱的正则匹配表达式。
本文旨在帮助开发同学们入门正则表达式,帮助大家在工作中把正则用起来,为逐步深入学习正则表达式做好铺垫。
阅读 110

天下事有难易乎? 为者,则难者亦易已;不为,则易者亦难矣!

4 声望
0 粉丝
0 条评论

天下事有难易乎? 为者,则难者亦易已;不为,则易者亦难矣!

4 声望
0 粉丝
宣传栏