正则表达式——常用正则表达式验证有效数字、密码、真实姓名、邮箱、身份证号码及其正则捕获懒惰性原理

常用正则表达式及其懒惰性原理

由两部分组成

  • 元字符

  • 量词元字符

*       0到多个
+       1到多个
?  		01{n} 	出现n次
{n,} 	出现到多次
{n,m} 	出现n到m次
  • 特殊元字符
\		转义字符(普通>特殊>普通)
.		除\n(换行符)以外任意字符
^		以哪一个元字符作为开始
$		以哪一个元字符作为结束
\n		换行符
\d		0~9之间一个数字
\D0~9之间任意字符
\w		数字、字母、下划线中的任意一个字符
\s		一个空白字符(包含空格、制表符、换页符)
\t		一个制表符(TAB键:四个空格)
x|y		x或者y中的一个字符
[xyz]	x或y或z中的一个字符
[^xy]	除了x/y以外的任意字符
[a-z]	指定a-z范围中的任意字符
[^a-z]	除了a-z范围中的任意字符
()		正则中的分组符号
(?:)	只匹配不捕获
(?=)	正向预查
(?!)	反向预查

//普通元字符:代表本身含义的
/xyz/	此正则匹配的就是"xyz"
// ^ $
let reg = /^\d/;	//必须以数字开始
reg.test("lele");		//false
reg.test("lele666");	//false
reg.test("666lele");	//true

let reg = /\d$/;	//必须以数字结束
reg.test("lele");		//false
reg.test("lele666");	//true
reg.test("666lele");	//false

let reg = /\d+/;		// ^ $都不加:字符串中包含符合内容规则即可

let reg = /^\d+$/;		// ^ $都加:字符串只能是和规则内容一致
reg=/^1\d{10}$/

// \ 转义字符 把特殊符号转换为普通符号
let reg = /^\d$/;
reg.test("\\d");		//false
reg = /^\\d$/;
reg.test("\\d");		//true

// x|y		()分组改变优先级,不包起来太乱了
let reg = /^(18|19)$/;

// []	1.中括号中出现的字符一般都代表本身的含义;2.\d在中括号中代表本身含义;3.中括号中不存在多位数;
let reg = /^[@+]+$/;

  • 修饰符
//正则表达式常用修饰符:img
i:ignoreCase		忽略大小写匹配
m:multiline			可以进行多行匹配
g:global			全局匹配
  • 常用的正则表达式
/*
1.验证是否为有效数字
	规则分析:
	1.可能出现+ -号,也可能不出现
	2.一位0-9都可以,多位首位不能是0
	3.小数不分可能有可能没有,一旦有后面必须有小数点+数字
*/
let reg = /^[+-]?\d|([1-9]\d+)(\.\d+)?$/;

/*
	2.验证密码
*/
let reg = /^\w{6,16}$/;

/*
3.验证真实姓名
	规则分析:
	1.汉字 [\u4E00-\u9FA5]
	2.名字长度 2~10
	3.可能有译名·汉字
*/
let reg = /^[\u4E00-\u9FA5]{2,10}(.[\u4E00-\u9FA5]){2,10}{0,2}$/;

/*
4.验证邮箱
	规则分析:
	\w+((-\w+)|(\.\w+))*  
	1.开头是数字字母下划线1到多位;
	2.还可以是“-数字字母下划线”或者“.数字字母下划线”,整体0到多位;
	邮箱的名字是由“数字、字母、下划线、-、.”组成的,但是-或.不能连续出现,也不能作为开始。
	@[A-Za-z0-9]+
	1.@后紧跟数字字母1到多位。
	((\.|-)[A-Za-z0-9]+)*
	1.对@后面名字的补充
	多域名    .com.cn
	企业邮箱   xxx@xxx.com
	\.[A-Za-z0-9]+
	1.这个匹配的是最后的域名(.com/.cn./.net/.edu......)
*/
let reg = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;

/*
5.验证身份证号码
	规则分析:
	1.18位
	2.最后一位可能是X
	身份证前六位是省市县    \d{6}
	中间8位是
	年                  (1|2)\d{3}或(\d{4})
	月                  \d[0-2]或(\d{2})
	日                  \d[1-9]或(\d{2})
	最后4位              \d{3}或(\d{2})
	最后一位 X或 数字      (\d|X)
	倒数第二位 偶数女 奇数男 (\d)
*/
let reg = /^\d{6}(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/;
  • 正则两种创建方式的区别
//1.字面量方式;
//2.构造函数方式;
let reg = /\d+/g;
//构造函数因为传递的是字符串,字符串中的\也有特殊意义。所以需要写\\才代表斜杠
let reg = new RegExp("\\d+","g");
//正则表达式中的部分内容是变量存储的;
//1.两个斜杠中包起来的都是元字符(如果正则中要包含某个变量值,则不能用字面量方式创建)。只能用构造函数方式,因为只有构造函数方式才能进行字符串拼接;
let type = "lele";
reg = /^@"+type +"@$/;	//错误
reg = new RegExp("^@"+type+"@$");
  • 正则的捕获

    实现正则捕获的方法:
    1. 正则RegExp.prototype上的方法
    exec:
    test:
    2.字符串String.prototype上支持正则表达式处理的方法
    match:
    replace:
    splite:

  • 基于exec实现正则捕获

    1.捕获的结果是null或者一个数组
    第一项:本次捕获到的内容
    其余项:对应小分组本次单独捕获的内容
    index:当前捕获内容在字符串中的起始索引
    input:原始字符串
    2.每执行一次exec,只能捕获到一个符合正则规则的,默认情况下,执行多少遍获取的结果都是第一个匹配到的,其余的捕获不到。
    **正则捕获懒惰性原因:**默认情况下lastIndex的值不会被修改,每一次都是从字符串开始位置查找,所以找到的永远是第一个。
    解决方案:全局修饰符g。
    注意:加了全局修饰符g后,基于test匹配验证后,lastIndex的值已经被修改为第一次匹配后的结果,所以下一次捕获不再从头开始了

  • 正则捕获懒惰性原理:
/*
	let str = "lele2020lele2021lele2022";
	let reg = /\d+/;
	reg.exec(str);
	//["2020", index: 4, input: "lele2020lele2021"]
	
	//实现正则捕获的前提是:当前正则要和字符串匹配,如果不匹配捕获的是null
	let str = "lele2020lele2021lele2022";
	let reg = /^\d+$/;
	reg.test(str);        //false
//===========================================
	let str = "lele2020lele2021lele2022";
	let reg = /\d+/;
	console.log(reg.lastIndex) //0
	//第一次捕获完成lastIndex没有改变,所以下一次exec还是从字符串开始位置开始查找,找到的永远第一个匹配到的。任何正则捕获的方法,都是这个机制。手动修改lastIndex不会改变正则中lastIndex的值。
	let reg = /\d+/g;
	console.log(reg.lastIndex) //11 设置全局匹配修饰符g后,第一次匹配完lastIndex会自己修改
	console.log(reg.lastIndex)       0
	reg.exec(str)                   ["2020"]
	console.log(reg.lastIndex)       8
	reg.exec(str)                   ["2021"]
	console.log(reg.lastIndex)       16
	reg.exec(str)                   ["2022"]
	//当全部捕获后,再次捕获,再次捕获的结果是null,d但是lastIndex又回归了初始值0,再次捕获又从第一个开始
	console.log(reg.lastIndex)       24
	reg.exec(str)                   null
	console.log(reg.lastIndex)       0
	reg.exec(str)                   ["2020"]
*/

自定义execAll方法,执行一次可以把所有匹配的结果捕获到(前提是设置了全局修饰符g)

~ function(){
	function execAll(str = ""){
	//进来之后先判断当前正则是否设置了g,不设置则不能进行循环捕获,否则会导致死循环
	//str:要匹配的字符串
	//this:RegExp的实例(当前操作的正则)
	//arr 存储最后所有捕获的信息,res存储每次捕获的内容
	if(!this.global) return this.exec(str);
	let arr = [];
	res = this.exec(str)
		while(res){
			//将每次捕获内容存到arr
			arr.push(res[0]);
			//只要捕获的内容不为null,则继续捕获下去
			res = this.exec(str);
		}
		return arr.length === 0 ? null : arr;
	}
	RegExp.prototypr.execAll = execAll;
}();

let reg = /\d+/g;
console.log(reg.execAll(str)); //["2020","2021","2022"]

字符串中的match方法,可以在执行一次的情况下,捕获到所有匹配的数据等同于execAll方法,(前提是设置了全局修饰符g)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值