1、前言
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
本文就针对正则表达式一般规则做简要介绍,适用于初学者学习细心阅读0.0。
2、正则表达式
1. 正则表达式的简介
正则表达式的一般形式如下,由注释符中间隔开:
//正则表达式的一般形式
var reg = /abc/g; // 全局匹配 abc 字符
正则表达式一般形式包含表达式本体source(代码中的/abc/)和修饰flag(代码中的g),修饰flag紧跟本体source。source属于必需,主要用来匹配对应的特定字符,flag属于非必需,主要用于控制匹配的一些因素,比如是否忽视大小写,多行匹配,全局匹配等。
正则表达式的创建方式一般有两种,一种通过正则表达式对象是RegExp创建,另一种通过两个/直接创建,一般创建方式如下:
//通过对象创建
var reg1 = new RegExp("111");
console.log(reg1); // 正则表达式为:/111/
//直接创建
var reg2 = /222/;
构造函数RegExp创建,可以接收第二个参数为flag;直接创建法的flag写在最后:
var reg1 = new RegExp("111","i"); // ignore忽视大小写
console.log(reg1); // 正则表达式为:/111/i
//直接创建
var reg2 = /222/i;
2. 正则表达式模式
在掌握基本的正则表达式创建,接下来就要开始了解正则的常用表达式和它的匹配规则了,正则表达式本身定义了很多的有意义的表达式,非常方便简化书写。以下表格列出常用表达式及描述,如下:
表达式 | 描述 |
---|---|
/d | 数字 |
/D | 非数字 |
/w | 字符串和数字和"_" |
/W | 非字符串和数字和"_" |
/b | 字符串 |
/B | 非字符串 |
/s | 空格 |
/S | 非空格 |
n+ | 匹配任何包含至少一个 n 的字符串 |
n* | 匹配任何包含零个或多个 n 的字符串 |
n? | 匹配任何包含零个或一个 n 的字符串 |
[abc] | 集合,表示查找方括号之间的任何字符 |
[0-9] | -可指定范围,这里表示查找从0至9的数字 |
(abc) | ()分组符,表示将abc捆绑在一起 |
(x|y) | 查找任何以|分隔的选项 |
^ | 在开头表示匹配输入的开始,如果不是在开头表示非 |
$ | 匹配输入的结束 |
. | 默认匹配除换行符之外的任何单个字符 |
{n} | 表示匹配前面字符出现n次 |
{n,} | 表示匹配前面字符至少出现n次 |
{n,m} | 表示匹配前面字符出现n到m次 |
上面例举了常用正则表达式匹配符号,需要熟记,刚看完可能没有什么感觉,那就实战出真知。
3. 正则表达式方法
在实战之前,率先拿好武器,所以先了解正则表达式的匹配方法。正则表达式常用的匹配方法主要有两个,分别是test()和exec();test()方法,接受字符串作为参数,返回boolean,表示匹配是否成功;exec()方法,也接受字符串,返回的是匹配到的结果。
// test方法,接受一个字符串,匹配成功则返回一个Boolean
var reg = /abc/i;
console.log(reg.test("abc")); //true 返回boolean型
// exec方法,也是接受一个字符串
console.log(reg.exec("abc")); // 返回类数组:["abc", index: 0, input: "abc", groups: undefined]
4. 正则表达式的实战练习
实战开始,话不多说:
// 匹配数字
var reg1 = /\d/; // 或者 reg1 = /[1-9]/
console.log(reg1.test("123")) //true
console.log(reg1.test("abc")) //false
//匹配字符串
var reg2 = /\w/; // 或者 reg2 = /[a-zA-Z0-9_]/
// 匹配多个
var reg3 = /\w+/ //不同于上面,这里可以匹配多个
console.log(reg2.exec("abcd")); // a
console.log(reg3.exec("abcd")); // abcd
熟能生巧,想必读者正则表达式的基本素养应该有了,那我们稍微再难一丢丢:
//匹配日期 ,日期年月日,可能隔开有_,-,/三种形式 (\为转义符)
var reg1 = /^\d{2,4}((\/|\-|\_)\d{1,2}){1,2}$/; // 年份可以2-4长度,月日1-2长度,可以没有日,隔开符可以/,-,_三种,必须是首尾。
console.log(reg1.test("1885_8_12")); // true
// 匹配邮箱
var reg2 = /^\w+@(\w+\.)+com$/; // 形似 xxx@xx.xx.com
console.log(reg2.test("123456@qq.com")); // true
// 匹配首尾空格
var reg3 = /(^\s*)|(\s*$)/
console.log(reg3.test(" / ")) // true
// 匹配url地址
var reg4 = /^https?:\/\/(\w+\.)+com(\/\w+)*\/?$/; // 形似 https://xxx.xxx.com/xxx/xxx
console.log(reg4.test("https://www.baidu.com/xxxx")) // true
对于()和[]的区别
()一般表示匹配的字符组,是捆绑在一起的,需要都符合
[]匹配的集合,集合一般无顺序,相当于每一个等价,有符合就行
但是()会继续相当于一个正则表达式匹配(看代码)
var str = 'abcdacd';
//案列一:
//需要bc两个都有
str.match(/a(bc)d/g); //result: [abcd]
//仅有bc其中一个就可
str.match(/a[bc]d/g); //result: [acd]
//案列二:
//匹配到结果,又将abcd作为输入,bc作为正则表达式,匹配出bc的结果放在了数组后面.
//即:/bc/.exec('abcd') // result:[bc]
/a(bc)d/.exec(str); //result: [abcd, bc]
//[]不会出现再匹配
/a[bc]d/.exec(str); //result: [abcd]
//如果不希望出现()的再匹配情况可以使用,非捕获符(?:)
/a(?:bc)d/.exec(str); //result: [abcd]
是不是有点感觉了呢,正则表达式在刚开始的时候可能没有感觉,多加练之后就习惯了。
如果上面的差不多都掌握了,那么我们继续稍扩充以下正则的规则。
5. 正则表达式模式二
继上面常用正则符号,如下是新的表达式:
表达式 | 符号 |
---|---|
(?:x) | 非捕获括号,匹配 'x' 但是不记住匹配项 |
x(?=y) | 匹配'x'仅仅当'x'后面跟着'y'.这种叫做先行断言,也有人称正向查找 |
(?<=y)x | 匹配'x'仅当'x'前面是'y'.这种叫做后行断言,也有人称反向查找 |
x(?!y) | 仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找 |
(?<!y)x | 仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找 |
上面的表达式稍微比前面的单个含义难一点,这里需要关联到匹配字符的前面或者后面,先看看理解理解,然后我们继续实战来看看一般如何使用:
// 匹配前面有a的b字符
var reg1 = /(?<=a)b/g;
console.log("abcbab".match(reg1)); // 输出[b,b]两个b,因为中间的b前面是c无法匹配到
// 匹配后面不是a的b字符
var reg2 = /b(?!a)/g;
console.log("bcbabb".match(reg2)); // 输出[b,b,b]三个b中间b后面有a
想必你已经有了大致了解了,因此接下来我们写一个实际运用的小测试:匹配html标签
// 匹配标签,一般标签都形似<div>前面有"<",后面有">",所以容易想到:
var reg3 = /(?<=\<)\w+(?=\>)/;
console.log("<div>".match(reg3)); // 输出div
// 但是想一想标签不可能这么简单,比如形似:<div class="name"></div> 匹配div上面的方式不可行
var reg4 = /(?<=\<\/)\w+(?=\>)/; //由于一般标签存在闭合标签,所以取巧使用闭合标签那部分匹配
console.log("<div class='name'></div>".match(reg4)); // 输出div
//但是不是所有都有单独闭合标签,比如形似<image id='id' src='./' />这种形式上面就又不可以了
var reg5 = /(?<=\<)\w+(?=\s)/; //观察发现标签前面为<后面为空格,因此取其中得到标签
console.log("<image id='id' src='./' />".match(reg5));
//综合上面,我们将两者合在一起
var reg6 = /(?<=\<)\w+(?=\s|\>)/; //使用或|
console.log("<image id='id' src='./' />".match(reg6)); // image
console.log("<div class='name'></div>".match(reg6)); // div
console.log("<div>".match(reg6)); // div
好的单个标签的匹配就讲到这里不再继续深入,转而,既然我们能够匹配标签了,那么标签里的内容是不是也就能够获取了呢?
//立刻想到
var reg1 = /(?<=\>)\w+(?=\<\/)/ //<>符号与上面匹配标签时相反,因为数据前面为>,后面为<
console.log("<div>xxx</div>".match(reg1)); // 返回xxx
// 对于标签嵌套,形似<div><div>xxxx</div><div>xxxxx</div></div>匹配
var reg2 = /(?<=\>)\w+(?=\<\/)/g; //加个全局匹配
console.log("<div><div>xxxx</div><div>xxxxx</div></div>".match(reg2)); // ["xxxx","xxxxx"]
感兴趣的小伙伴可以继续深入其他情况,强大的Vue的编译方式也是使用了大量的正则来匹配标签变量的,要复杂的多,只是本文仅对一般形式做出匹配,不再深入。
6. 可操控正则表达式的一般使用方法
在基本了解正则之后,就要使用正则了,因此列举常用有关正则的方法。
前面已经提到过正则的方法常用有两个,这里再次列举出来:
//返回一个boolean,匹配到则返回true,未匹配到返回fasle
reg.test("string");
//返回第一个被匹配到的字符串。包括下标,输入内容
reg.exec("string")
然后还有,字符串的方法,可以以正则表达式作为参数的方法,常用有四个:
//字符串拆分可接受正则
str.split();
//匹配可接受正则
str.match();
//替换可接受正则
str.replace();
//寻找可接受正则
str.search();
//示例
var str = "abcda";
var reg = /a/g;
var s = str.replace(reg, "z");
console.log(s); // zbcdz
7. 关于正则lastIndex的小细节
一个需要注意的细节,正则表达式有一个lastIndex的属性值,表示正则表达式匹配的开始下标位置,即正则表达式匹配的开始位置。先上代码,看以下的情形:
//实例一
var reg1 = /a/g;
var str1= "abc"
reg1.test(str1); //true
console.log(reg1.lastIndex); // 1
reg1.test(str1); //false ,再次匹配居然false
//实例二
var reg = /1/g;
var str = "123123";
reg.lastIndex = 2;
reg.exec(str); // 返回的下标为3,居然而不为1,因为字符匹配的起始位置被设定为了2;
在有全局搜索时(正则有g修饰符),搜索的起点由lastIndex表示(初始lastIndex为0),所以会出现上面两次执行test第二次居然失败的问题,因此处理方式是当执行一次搜索后,将lastIndex置零就可以。
var reg1 = /a/g;
var str1= "abc"
reg1.test(str1); //true
reg1.lastIndex = 0
reg1.test(str1); //true 返回true因为从头匹配。
8. 常用的正则表达式
本文末尾例举一些常用的正则表达式,以供方便查阅使用,不过既然授之以渔,查阅的就不多写了:
需求 | 表达式 |
---|---|
匹配正数,负数,小数 | /^(-|+)?\d+(.\d+)?$/ |
匹配汉字 | /^[\u4e00-\u9fa5]{0,}$/ |
匹配邮箱 | /^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$/ |
匹配网址 | /[a-zA-z]+://[^\s]/ 或 /^http://([\w-]+.)+[\w-]+(/[\w-./?%&=])?$/ |
匹配身份证 | /^\d{15}|\d{18}$/ |
匹配强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间) | /^(?=.\d)(?=.[a-z])(?=.*[A-Z]).{8,10}$/ |
匹配日期格式 | /^\d{4}-\d{1,2}-\d{1,2}/ |
匹配IP地址 | /\d+.\d+.\d+.\d+/ |
.......
9. 尾语
本文介绍了正则的一般使用,如有错误,望请指正!欢迎转载,转载前请先联系作者,谢谢!
网友评论