第二十八章.正则表达式二
- 其他字符特殊字符
/*
* | 或者
*
* ^ 起始位置
* $ 结束位置
*
* . 匹配所有字符(除了 \n \r)
*
* */
let str = "abcd";
let str2 = "abd";
let reg = /abc|d/g;// | 或者
let reg2 = /ab(c|d)/g;// 和ab[cd]
console.log(str.match(reg));//["abc", "d"]
console.log(str2.match(reg));//["d"]
console.log(str.match(reg2));//["abc"]
let str = "aabc";
let reg = /^abc$/;//必须以a开头c结尾
console.log(str.match(reg));//null
//假若有一个需求匹配QQ号
// 5~10
let str = "3003354138";
let reg = /^[1-9]\d{4,9}$/;
console.log(str.match(reg));
//["3003354138", index: 0, input: "3003354138", groups: undefined]
//注意:不能用\b来匹配
let str = "22 3003354138 22";
let reg = /\b[1-9]\d{4,9}\b/;
console.log(reg.test(str));//true
//明显可以看出字符串不是一个合法的QQ号,但匹配成功了!
let str = '\n';//回车
let reg = /./;
console.log(reg.test(str));//false
//. 匹配所有字符(除了 \n \r)
- 捕获组
/*
* 捕获组
* \1
*
* 对子项的重复
*
* */
let str = "123aaa321";
let reg1 = /\d{3}aaa\d{3}/;
let reg2 = /(\d{3})aaa(\d{3})/; //量词是把整个正则规则重复
let reg3 = /(\d{3})aaa\1/; //捕获组是把匹配结果重复 \1捕获组 第一个子项
console.log(str.match(reg1));//["123aaa321", index: 0, input: "123aaa321", groups: undefined]
console.log(str.match(reg2));// ["123aaa321", "123", "321", index: 0, input: "123aaa321", groups: undefined]
console.log(str.match(reg3));//null
/*
console.log(RegExp.$1);//123
console.log(RegExp.$2);//321
*/
- 断言
/*
*前瞻断言
* 语法为:x(?=y),它表示 “匹配 x, 仅在后面是 y 的情况"”
*/
let str = "1 turkey costs 30€";
alert( str.match(/\d+(?=€)/) ); // 30 (正确地跳过了单个的数字 1)
另一种情况:这次我们想要一个数量,它是一个不被 €
跟着的数值。
/*
*前瞻否定断言
* 语法为:x(?!y),意思是 “查找 x, 但是仅在不被 y 跟随的情况下匹配成功”。
*/
let str = "2 turkeys cost 60€";
alert( str.match(/\d+(?!€)/) ); // 2(正确地跳过了价格)
/*后瞻断言
前瞻断言允许添加一个“后面要跟着什么”的条件判断。
后瞻断言也是类似的,只不过它是在相反的方向上进行条件判断。也就是说,它只允许匹配前面有特定字符串的模式。
语法为:
后瞻肯定断言:(?<=y)x, 匹配 x, 仅在前面是 y 的情况。
后瞻否定断言:(?<!y)x, 匹配 x, 仅在前面不是 y 的情况。
*/
let str = "1 turkey costs $30";
//把价格换成美元。美元符号通常在数字之前
alert( str.match(/(?<=\$)\d+/) ); // 30 (跳过了单个的数字 1)
//为了找到数量 —— 一个前面不带 $ 的数字
alert( str.match(/(?<!\$)\d+/) ); // 2 (跳过了价格)
- 常用正则
/*
* 常用正则
* */
let Reg = {
//QQ 5-10位数字,不能以0开头
qq : /^[1-9]\d{4,9}$/,
//用户名 6-16位 数字 字母 _ 不能以数字开头
user : /^[a-z_]\w{5,15}$/i,
//密码 8-16位 数字 字母 <>,.?/:;"'{}[]|!@#$%^&*()-+_
pwd : /^[<>,?/:;"'{}|!@#$%^&*()+=\w\-\.\[\]]{8,16}$/,
//手机号 11位 第一位是1,第二位不能是0 1和2,其他的没有要求
tel : /^1[3-9]\d{9}$/,
//邮箱 @xx.com.cn
mail : /^\w+@([a-z\d]+){1,2}(\.[a-z]{2,}){1,2}$/i
};
/* let str = '44442423423';
if (/^\d+$/.test(str)){
console.log("不满足规则,密码不能纯数字");
}else if ( /^[a-z]+$/i.test(str) ){
console.log("不满足规则,密码不能纯字母");
}else if (Reg.pwd.test(str)){
console.log("满足规则");
}else{
console.log("不满足规则");
}*/
- replace
let str = "北京是一个繁华的大都市,北京是一座让人向往城市。";
let reg = /北京/g;
//console.log(str.match(reg));// ["北京", "北京"]
let newStr = str.replace(reg,"上海");
console.log(newStr);//上海是一个繁华的大都市,长沙是一座让人向往城市。
//脏字过滤
let str = "操!傻逼,你玩你妈呢。你大爷";
let reg = /傻逼|你妈|操|你爸|垃圾|废物|你大爷/g;
let newStr = str.replace(reg,($0)=>{
/*形参名字随便写
第一个形参:每次匹配的整体内容
第二个形参:第一个子项
第三个形参:第二个子项
以此类推
*
* */
// console.log($0);
return "*".repeat($0.length);
});
console.log(newStr);//*!**,你玩**呢。***
- 案例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="Anthor" content="阿飞老师" />
<title>Title</title>
<style>
*{ margin:0; padding:0; font-family:"Microsoft yahei",serif;}
li{ list-style-type: none;}
#box{
position: relative;
width: 420px;
height: 540px;
background: #0cf;
margin: 50px auto 0;
}
#box h2{
background: #09c;
height: 40px;
line-height: 40px;
color: #fff;
font-size: 20px;
text-align: center;
}
#box ul li{
overflow: hidden;
position: relative;
height: 42px;
margin:23px 0;
transition: height .3s;
}
#box ul li.wrong{
height: 62px;
}
#box ul li.right{
height: 42px;
}
#box ul li input{
position: relative;
z-index: 1;
display: block;
width: 270px;
height: 40px;
text-indent: 15px;
border: 1px solid #ccc;
outline: none;
margin: 0 auto;
}
#box ul li input:focus{
border: 1px solid pink;
}
#box ul li.wrong input{
border-color: red;
}
#box ul li.right input{
border-color: #00ae00;
}
#box ul li p.tip{
overflow: hidden;
height: 20px;
line-height: 20px;
color: #fb0021;
margin-left: 75px;
font-size: 12px;
}
#box ul li p.pass{
display: none;
position: absolute;
right: 46px;
top: 10px;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
background: #4bba68;
color: #fff;
font-size: 12px;
font-weight: bolder;
border-radius: 50%;
box-shadow: 1px 1px 5px #000;
}
#box ul li.right p.pass{
display: block;
}
#tip{
position: absolute;
z-index: 0;
top: 40%;
left: 50%;
margin-left: -75px;
margin-top: -20px;
width: 150px;
height: 40px;
line-height: 40px;
text-align: center;
background: #000000;
color: #ffffff;
font-size: 12px;
font-weight: bolder;
opacity: 0;
transition: opacity .3s,top .3s;
}
#tip.show{
z-index: 99;
opacity: 1;
top: 50%;
}
#sub{
display: block;
width: 270px;
height: 40px;
background: #09c;
border: 1px solid #ccc;
outline: none;
margin: 10px auto 0;
color: #fff;
font-weight: bolder;
}
</style>
</head>
<body>
<div id="box">
<h2>注册</h2>
<ul>
<li>
<input type="text" name="user" class="first" placeholder="请输入您的用户名">
<p class="tip">错误:用户名格式不正确</p>
<p class="pass">√</p>
</li>
<li>
<input type="password" name="pwd" class="first" placeholder="请输入您的密码">
<p class="tip">错误:密码格式不正确</p>
<p class="pass">√</p>
</li>
<li>
<input type="password" class="second" placeholder="请再次输入您的密码">
<p class="tip">错误:两次密码输入不一致</p>
<p class="pass">√</p>
</li>
<li>
<input type="text" name="tel" class="first" placeholder="请输入您的手机号">
<p class="tip">错误:手机号格式不正确</p>
<p class="pass">√</p>
</li>
<li>
<input type="text" name="QQ" class="first" placeholder="请输入您的QQ号">
<p class="tip">错误:QQ号格式不正确</p>
<p class="pass">√</p>
</li>
<li>
<input type="text" name="email" class="first" placeholder="请输入您的邮箱">
<p class="tip">错误:邮箱格式不正确</p>
<p class="pass">√</p>
</li>
</ul>
<div id="tip">请先填写密码!!</div>
<input id="sub" type="submit" value="提交">
</div>
<script>
(function(){
//正则规则
let Reg = {
//QQ 5-10位数字,不能以0开头
QQ : /^[1-9]\d{4,9}$/,
//用户名 6-16位 数字 字母 _ 不能以数字开头
user : /^[a-z_]\w{5,15}$/i,
//密码 8-16位 数字 字母 <>,.?/:;"'{}[]|!@#$%^&*()-+_
pwd : /^[<>,?/:;"'{}|!@#$%^&*()+=\w\-\.\[\]]{8,16}$/,
//手机号 11位 第一位是1,第二位不能是0 1和2,其他的没有要求
tel : /^1[3-9]\d{9}$/,
//邮箱 @xx.com.cn
email : /^\w+@([a-z\d]+){1,2}(\.[a-z]{2,}){1,2}$/i
};
/*
* 0 用户名
* 1 密码
* 2 再次输入密码
* 3 手机号
* 4 qq号
* 5 邮箱
* */
let aInput = document.querySelectorAll("#box ul li input");
let oTip = document.getElementById("tip");
let timer = null;
//除了再次输入密码之外的其他input加事件
aInput.forEach((n,i)=>{
if(i === 2)return;
n.onblur = function(){
//获取当前input的内容
let val = this.value;
//没有输入内容的话,不需要判断
if(!val) {
this.parentNode.className = '';
return;
}
//调用对应的正则做验证
let reg = Reg[this.name];
//test验证
if (reg.test(val)){
//验证通过
this.parentNode.className = "right";
}else{
//验证不通过
this.parentNode.className = "wrong";
//不通过不让离开焦点
this.focus();
}
};
});
//再次输入密码框的事件
aInput[2].onfocus = function(){
//获得焦点的时候,要判断密码框有没有内容
//如果密码框没有输入内容,直接让密码框获得焦点
if (!aInput[1].value){
aInput[1].focus();
oTip.className = "show";
clearTimeout(timer);
timer = setTimeout(()=>{
oTip.className = "";
},2000);
}
};
aInput[2].onblur = function(){
let val = this.value;
//没有输入内容的话,不需要判断
if(!val) {
this.parentNode.className = '';
return;
}
//有内容,和密码框做判断
if (val === aInput[1].value){
//验证通过
this.parentNode.className = "right";
}else{
//验证不通过
this.parentNode.className = "wrong";
//不通过不让离开焦点
aInput[1].focus();
}
};
})();
</script>
</body>
</html>