JavaScript 正则表达式
正则表达式(英文:Regular Expression,在代码中常简写为regex、regexp或者RE)使用单个字符串来描述、匹配一系列符合某个语法规则的字符串搜索模式。
什么是正则表达式?
- 正则表达式是由一个字符序列形成的搜索模式
- 正则表达式可以是一个简单的字符,或一个更复杂的模式
- 正则表达式可以用于所有文本搜索和文本替换的操作
正则表达式的定义
- 字面量定义:
/正则表达式主体/修饰符(可选)
- 构造函数定义
RegExp(正则表达式, 修饰符);
- new RegExp("\d", g);
- 参数1表示正则表达式的表达体
- 参数2表示正则表达式的修饰符
- new RegExp("\d", g);
正则表达式作用
- 用于判断给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”)
- 可以通过正则表达式,从字符串中获取我们想要的特定部分
符号
正则表达式由普通字符、转义字符和特殊字符(元字符)组成。
下面是一些常用的转义字符:
转义字符 | 描述 |
---|---|
\d | 表示所有的数字 |
\D | 表示所有的非数字 |
\w | 表示所有的数字、字母、下划线 |
\W | 表示所有的非数字、字母、下划线 |
\s | 表示所有的空白符 |
\S | 表示所有的非空白符 |
\b | 表示单词的边界 |
\B | 表示非单词的边界 |
下面是一些特殊字符(元字符):
特殊字符(元字符) | 描述 |
---|---|
. | 表示除了回车和换行之外的其他所有内容 |
() | 表示一个分组,一个分组是一个整体 |
[] | 表示一个范围 |
{} | 表示数量,可以是一个参数或者两个参数,参数是非负整数。{n}表示匹配n次,{n,}表示至少匹配n次,{n, m}表示至少匹配n次且至多匹配m次 |
| | 表示或者,将两个匹配条件进行逻辑“或”运算 |
? | 表示零个或一个 |
* | 表示零个或多个 |
+ | 表示一个或多个 |
^ | 表示开始 |
$ | 表示结束 |
[^] | 表示取反 |
\< | 表示匹配词(word)的开始 |
\> | 表示匹配词(word)的结束 |
速记理解技巧
“.
、[]
、^
、$
”这四个字符是所有语言都支持的正则表达式,所以这四个是基础的正则表达式。
正则难理解,是因为里面有一个等价的概念,这个概念大大增加了理解难度,让很多初学者看起来会懵,如果把等价都恢复成原始写法,自己书写正则就超级简单了,就像说话一样去写你的正则了:
等价:等价是等同于的意思,表示同样的功能,用不同符号来书写。
?
、*
、+
、\d
、\w
都是等价字符?
等价于匹配长度{0, 1}
*
等价于匹配长度{0,}
+
等价于匹配长度{1,}
\d
等价于[0-9]
\D
等价于[^0-9]
\w
等价于[a-zA-Z0-9_]
\W
等价于[^a-zA-Z0-9_]
正则表达式与字符串方法的搭配使用
- split()
let str = "abc def ghi jkl";
let arr = str.split(/\s+/);
console.log(arr); // ["abc", "def", "ghi", "jkl"]
- match()
let str = "abcdaaaefghijka";
let result1 = str.match("a");
let result2 = str.match(/a/g);
console.log(result1); // 输出a和第一次匹配到的索引值,["a", index: 0, input: "abcdaaaefghijka", groups: undefined]
console.log(result2); // 输出所有的a,["a", "a", "a", "a", "a"]
- search()
let str = "bcdaaaefghijka";
let result1 = str.search(/a/g);
console.log(result1); // 输出第一次匹配到a的索引值,3
- replace()
- replace()接收两个参数:
- 参数1是被替换下的内容,可以是字符串,也可以是正则表达式
- 参数2是被替换上的内容,可以是字符串,也可以是函数
- replace()接收两个参数:
let str = "abcaadefaaghiaja";
let str1 = str.replace(/a/g,"*");
console.log(str1); // 将字符串里面的a全部替换成*,*bc**def**ghi*j*
let str = "abcaadefaaghiaja";
let str1 = str.replace(/a/g, function(...args){
console.log(args);
});
let str = "abcaadefaaghiaja";
let str2 = str.replace(/a/g, function(match, index){
console.log(match, index);
// 这个函数的返回值就是被替换上的内容
return "*";
});
console.log(str2);
在replace()中参数1的正则表达式中有几个()分组,那么参数2中的函数的参数就对应增加几个成员:
let str = "abcafadefaagfhfiaja";
let str3 = str.replace(/(a)|(f)/g, function(match, $1, $2, index){
console.log(match, $1, $2, index);
return "*";
});
console.log(str3);
使用正则表达式模仿百度账号注册的表单验证
如下是源码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.register{
position: relative;
width: 400px;
height: auto;
padding: 20px;
margin: 100px auto;
border: 1px solid #CCC;
border-radius: 30px;
}
.item{
display: flex;
justify-content: space-around;
align-items: center;
width: 400px;
height: 60px;
}
.item label{
flex: 2;
cursor: pointer;
font-weight: bold;
}
.item input{
flex: 7;
outline: none;
height: 30px;
}
.registerBtn{
justify-content: center;
width: 400px;
height: 50px;
outline: none;
cursor: pointer;
font-weight: bold;
border-top-right-radius: 25px;
border-top-left-radius: 25px;
border-bottom-right-radius: 25px;
border-bottom-left-radius: 25px;
}
.userNamePrompt,.phonePrompt,.passWordPrompt1,.passWordPrompt2,.codePrompt p{
width: 400px;
height: 20px;
text-align: center;
color: red;
font-size: 14px;
}
.codeItem{
width: 400px;
height: 60px;
display: flex;
justify-content: space-between;
align-items: center;
}
.codeItem label{
font-weight: bold;
cursor: pointer;
}
.codeItem .code{
width: 30%;
text-align: center;
cursor: pointer;
font-size: 24px;
}
.codeItem .checkCode{
width: 40%;
}
.codeItem input{
height: 30px;
outline: none;
}
</style>
</head>
<body>
<div id="register" class="register">
<form action="" method="">
<div class="item">
<label for="userName">用户名:</label><input type="text" id="userName" class="userName" placeholder="请设置用户名">
</div>
<div id="userNamePrompt" class="userNamePrompt"><p></p></div>
<div class="item">
<label for="phone">手机号:</label><input type="text" id="phone" class="phone" placeholder="用于登录和找回密码">
</div>
<div id="phonePrompt" class="phonePrompt"><p></p></div>
<div class="item">
<label for="passWord1">密码:</label><input type="password" id="passWord1" class="passWord1" placeholder="请设置登录密码">
</div>
<div id="passWordPrompt1" class="passWordPrompt1"><p></p></div>
<div class="item">
<label for="passWord2">确认密码:</label><input type="password" id="passWord2" class="passWord2" placeholder="请确认登录密码">
</div>
<div id="passWordPrompt2" class="passWordPrompt2"><p></p></div>
<div class="codeItem">
<label for="checkCode">验证码:</label>
<input type="text" id="checkCode" class="checkCode" placeholder="请输入验证码">
<input type="text" id="code" class="code" readonly>
</div>
<div id="codePrompt" class="codePrompt"><p></p></div>
<div class="item">
<button id="registerBtn" class="registerBtn">注册</button>
</div>
</form>
<script>
// 用户名规则:用户名不能超过7个汉字或14个字符,不能是纯数字
// 手机号:遵守手机号规则
// 密码规则:1、长度为8~14个字符 2、字母、数字及标点符号至少包含2种 3、不允许有空格、中文
// 获取元素
let userName = document.getElementById("userName");
let phone = document.getElementById("phone");
let passWord1 = document.getElementById("passWord1");
let passWord2 = document.getElementById("passWord2");
let code = document.getElementById("code");
let checkCode = document.getElementById("checkCode");
let registerBtn = document.getElementById("registerBtn");
let userNamePrompt = document.querySelector(".userNamePrompt p");
let phonePrompt = document.querySelector(".phonePrompt p");
let passWordPrompt1 = document.querySelector(".passWordPrompt1 p");
let passWordPrompt2 = document.querySelector(".passWordPrompt2 p");
let codePrompt = document.querySelector(".codePrompt p");
// 阻止button的默认行为
registerBtn.onclick = function(e){
// 浏览器兼容处理
let event = e || window.event;
// 高级浏览器阻止默认行为
event.preventDefault;
// IE阻止默认行为
event.returnValue = false;
}
// 用户名输入框失去焦点事件
userName.onblur = function(){
// 获取用户名输入框内容
let userNameContext = this.value;
// 如果输入框为空,清除提示信息
if(userNameContext === ""){
userNamePrompt.innerHTML = "";
}else{
// 用户名不能超过7个汉字或14个字符
let reg1 = /^([\u4e00-\u9fa5]{1,7}|\w{1,14})$/;
// 验证是否符合要求
let result1 = reg1.test(userNameContext);
// 如果不符合要求,则显示提示
if(!result1){
userNamePrompt.innerHTML = "用户名不能超过7个汉字或14个字符";
return;
}else{
userNamePrompt.innerHTML = "";
}
// 用户名不能是纯数字
let reg2 = /^\d+$/;
// 验证是否符合要求
let result2 = reg2.test(userNameContext);
// 如果输入的用户名是纯数字,则不符合要求,显示提示
if(result2){
userNamePrompt.innerHTML = "用户名仅支持中英文、数字和下划线且不能为纯数字";
return;
}else{
userNamePrompt.innerHTML = "";
}
}
}
// 手机号输入框失去焦点事件
phone.onblur = function(){
// 获取手机号输入框内容
let phoneContext = this.value;
// 如果输入框为空,清除提示信息
if(phoneContext === ""){
phonePrompt.innerHTML = "";
}else{
// 手机号格式
let reg1 = /^1[34578]\d{9}$/;
// 验证是否符合要求
let result1 = reg1.test(phoneContext);
// 如果不符合要求,显示提示信息
if(!result1){
phonePrompt.innerHTML = "手机号输入错误";
return;
}else{
phonePrompt.innerHTML = ""
}
}
}
// 密码输入框失去焦点事件
passWord1.onblur = function(){
// 获取密码输入框内容
let = passWordContext = this.value;
// 如果输入框为空,清除提示信息
if(passWordContext === ""){
passWordPrompt1.innerHTML = "";
}else{
// 密码不能有空格、中文
let reg1 = /[\s\u4e00-\u9fa5]/;
// 验证是否符合要求
let result1 = reg1.test(passWordContext);
// 如果输入的密码中包含空格、中文,则不符合要求,显示提示
if(result1){
passWordPrompt1.innerHTML = "密码不允许包含空格、中文字符";
return;
}else{
passWordPrompt1.innerHTML = "";
}
// 检测是否有数字
let reg2 = /\d/;
let result2 = reg2.test(passWordContext);
// 检测是否有字母
let reg3 = /[a-zA-Z]/;
let result3 = reg3.test(passWordContext);
// 检测是否有标点符号
let reg4 = /[\!\@\#\$\%\^\&\*\(\)\_\?\>\<\+\*\/\-]/;
let result4 = reg4.test(passWordContext);
// 将检测到的结果存入数组
let arr = [reg2, reg3, reg4];
// 定义一个变量用于计算数组中成员是true的数量
let num = 0;
// 遍历数组
arr.forEach(function(value, index, self){
if(value){
num++;
}
});
// 如果密码中不包含数字、字母及标点符号中至少两种,则不符合要求,显示提示信息
if(num < 2){
passWordPrompt1.innerHTML = "密码必须至少包含字母、数字及标点符号中的2种";
return;
}else{
passWordPrompt1.innerHTML = "";
}
// 密码长度为8~14个字符
if(passWordContext.length < 8 || passWordContext.length > 14){
passWordPrompt1.innerHTML = "密码长度为8~14个字符";
return;
}
}
}
// 确认密码输入框失去焦点事件
passWord2.onblur = function(){
// 获取密码输入框内容
let passWordContext1 = passWord1.value;
// 获取确认密码输入框内容
let passWordContext2 = this.value;
// 如果输入框为空,清除提示信息
if(passWordContext2 === ""){
passWordPrompt2.innerHTML = "";
}else{
// 检查两个密码是否相同,如果不相同,显示提示信息
if(passWordContext1 !== passWordContext2){
passWordPrompt2.innerHTML = "两次密码不一致";
return;
}else{
passWordPrompt2.innerHTML = "";
}
}
}
// 调用函数产生验证码
code.value = rand(6);
// 点击刷新验证码
code.onclick = function(){
// 调用函数
let num = rand(6);
this.value = num;
};
// 验证码函数
function rand(number){
// 存储验证码
let codeNum = "";
// 循环生成验证码
for (let i = 0; i < number; i++){
// 验证码随机颜色
let r = Math.floor(Math.random()*256);
let g = Math.floor(Math.random()*256);
let b = Math.floor(Math.random()*256);
let codeColor = "rgb" + "(" + r + "," + g + "," + b + ")";
code.style.color = codeColor;
// 验证码
codeNum += Math.floor(Math.random() * 10);
}
return codeNum;
}
// 验证码输入框失去焦点事件
checkCode.onblur = function(){
// 获取验证码输入框内容
let checkCodeVal = this.value;
// 获取验证码内容
let codeVal = code.value;
// 如果输入框为空,清除提示信息
if(checkCodeVal === ""){
codePrompt.innerHTML = "";
}else{
// 校验验证码
if(checkCodeVal !== codeVal){
codePrompt.innerHTML = "验证码不正确";
// 重新调用函数,生成新的验证码
code.value = rand(6);
return;
}else{
codePrompt.innerHTML = "";
}
}
}
</script>
</div>
</body>
</html>
通过正则实现字符串替换1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="box" class="box"></div>
<script>
/*
有如下字符串:var str = `<table><tr><td id="u{{id}}">{{id}}</td></tr><tr><td title="{{name}}">{{name}}</td></tr></table>`;
结合对象: var user = {id: "1234", name: "tony"};
变为: <table><tr><td id="u1234">1234</td></tr><tr><td title="tony">tony</td></tr>
*/
let box = document.getElementById("box");
let str = `
<table>
<tr>
<td id="u{{id}}">{{id}}</td>
</tr>
<tr>
<td title="{{name}}">{{name}}</td>
</tr>
</table>
`;
let user = {
id: "1234",
name: "tony"
};
let str1 = str.replace(/{{(\w+)}}/g, function(match, $1) {
return user[$1];
});
console.log(str1);
box.innerHTML = str1;
// match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
</script>
</body>
</html>
通过正则实现字符串替换2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
/*
有如下字符串
var url = "cid=123&type=image&startTime=2017";
请写一个函数,传入url,返回如下对象
{cid: 123, type: "image", startTime: 2017}
*/
let url = "cid=123&type=image&startTime=2017";
let fun = function(url){
// 将=替换成:
let str1 = url.replace(/\=/g, ":");
// console.log(str1);
// 将&替换成,
let str2 = str1.replace(/\&/g, ",");
// console.log(str2);
// 为字符串头尾添加花括号
let str3 = "{" + str2 + "}";
// console.log(str3);
// 将字符串里面的所有属性、属性值添加双引号
var reg = /([^\s\:\{\[\,]+)\s*\:([^\s\{\[\,\}]+)\s*/g;
var str4 = str3.replace(reg, "\"$1\":\"$2\"");
// console.log(str4);
let obj = JSON.parse(str4);
console.log(obj);
return obj;
}
fun(url);
</script>
</body>
</html>