正则表达式
JavaScript正则表达式是前端开发中不可或缺的核心技能,它能高效处理字符串匹配、查找、替换和验证等任务。
一、JavaScript正则表达式基础
1. 创建方式
字面量形式:/pattern/flags(性能更优,适用于静态模式)
javascript
const reg1 = /^(13[0-9]|14[01456879]|15[0-345-9]|16[23456789]|17[0-9]|18[0-9]|19[0-345-9])\d{8}$/; // 手机号校验
构造函数形式:new RegExp('pattern', 'flags')(支持动态拼接字符串)
javascript
const pattern = "/^(13[0-9]|14[01456879]|15[0-345-9]|16[23456789]|17[0-9]|18[0-9]|19[0-345-9])\d{8}$/"; // 注意双重转义
const reg2 = new RegExp(pattern);
2. 常用修饰符(Flags)
g:全局匹配(不加则仅匹配首个)i:忽略大小写m:多行模式(使^和$匹配每行起止)s:dotAll模式(使.匹配换行符)u:Unicode模式(支持四字节UTF-16字符)y:粘连模式(强制从lastIndex位置开始匹配)
3. 核心元字符
- 字符匹配:
.(任意非换行字符)、\d(数字)、\w(字母数字下划线)、\s(空白符) - 边界定位:
^(行首)、$(行尾)、\b(单词边界) - 量词:
*(0次或多次)、+(1次或多次)、?(0次或1次)、{n,m}(n到m次) - 分组:
()(捕获组)、(?:)(非捕获组) - 断言:
(?=...)(前瞻肯定)、(?!...)(前瞻否定)、(?<=...)(后瞻肯定)
4. 常用方法
- RegExp对象方法:
test(str):返回布尔值,常用于表单验证exec(str):返回匹配结果数组,支持全局匹配循环
- String对象方法:
match(reg):返回所有匹配项数组replace(reg, newStr):字符串替换split(reg):按正则分割字符串search(reg):返回首个匹配索引
二、项目中高频使用的正则校验规则
1. 基础数据校验
手机号验证
javascript
// 基础版:13-19开头,共11位
const phoneReg = /^1[3-9]\d{9}$/;
// 增强版
const enhancedPhoneReg = /^(13[0-9]|14[01456879]|15[0-345-9]|16[23456789]|17[0-9]|18[0-9]|19[0-345-9])\d{8}$/;
- 使用示例:
phoneReg.test('13812345678')→true - 注意:需结合运营商号段演进(如19x、166、167等)定期更新规则
邮箱验证
javascript
// 基础版:支持子域名和国际化域名
const emailReg = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
// 严格版
const strictEmailReg = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
- 关键点:需排除连续点号、开头结尾点号等非法结构
验证身份证号码
javascript
// 18位身份证
const idCardReg = /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X|x)$/;
// 15位身份证(旧版)
const oldIdCardReg = /^\d{15}$/;
2. 表单验证常用规则
密码强度验证
javascript
// 基础版:至少8位,含大小写字母和数字
const pwdReg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;
// 增强版:增加特殊字符要求
const strongPwdReg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*?]).{8,20}$/;
- 说明:
(?=...)为正向肯定预查,确保包含指定字符类型
验证姓名
javascript
// 2-4个汉字
const nameReg = /^[\u4e00-\u9fa5]{2,4}$/;
// 2-10个汉字(更宽松)
const flexibleNameReg = /^[\u4e00-\u9fa5]{2,10}$/;
// const nameReg = /^([a-zA-Z\u4e00-\u9fa5]{1,10})$/;
日期格式验证
javascript
// YYYY-MM-DD格式
const dateReg = /^\d{4}-\d{2}-\d{2}$/;
// 24小时制时间格式
const timeReg = /^([0-9]|2[0-3]):[0-5][0-9]$/;
```<websource>source_group_web_5</websource>
### 3. 高级校验场景
#### URL参数解析
```javascript
// 精确捕获键值对,支持数组型参数
const urlParamReg = /([^?&=#]+)=([^&=#]*)/g;
// 使用示例
const params = {};
'query=js&tag=regex&tag=validation'.replace(urlParamReg, (_, key, value) => {
params[key] = params[key] ? [...params[key], value] : value;
});
- 优势:比传统split('&')更健壮,自动解码encodeURIComponent编码内容
字符串处理技巧
javascript
// 手机号脱敏:保留前3位+后4位
const mobile = '15812345678';
const maskReg = /^(\d{3})\d{4}(\d{4})$/;
console.log(mobile.replace(maskReg, '$1****$2')); // 158****5678
// 日期格式转换:YYYY-MM-DD → MM/DD/YYYY
const date = '2025-03-31';
console.log(date.replace(/(\d{4})-(\d{2})-(\d{2})/, '$2/$3/$1')); // 03/31/2025
三、正则表达式实战技巧与最佳实践
1. 贪婪匹配与懒惰匹配
javascript
'12345678'.match(/\d{3,6}/); // 匹配 ["123456"]
- 懒惰模式(加
?):尽可能少匹配字符
javascript
'12345678'.match(/\d{3,6}?/); // 匹配 ["123"]
- 应用场景:提取HTML标签内容时避免匹配过长片段
2. 分组与捕获技巧
- 捕获组:
()包裹的内容可通过$1、$2引用
javascript
'2025-03-31'.replace(/(\d{4})-(\d{2})-(\d{2})/, '$2/$3/$1');
- 非捕获组:
(?:...)仅分组不捕获,提升性能
javascript
/(?:\d{2})-(\d{2})/ // 只捕获后两位
- 命名捕获组:ES2018支持,通过名称访问
javascript
const reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const { groups } = reg.exec('2025-03-31');
console.log(groups.year); // "2025"
3. 前瞻断言与后瞻断言
- 正向先行断言:匹配后面是特定内容的字符串
javascript
// 匹配后面是"px"的数字
const reg = /\d+(?=px)/;
'100px'.match(reg); // ["100"]
- 负向后行断言:匹配前面不是特定内容的字符串
javascript
// 匹配前面不是"$"的数字
const reg = /(?<!\$)\d+/;
'100'.match(reg); // ["100"](匹配成功)
'price:$100'.match(reg); // [](不匹配)
4. 性能优化建议
- 避免回溯爆炸:使用原子组
(?>...)防止过度回溯 - 预编译正则:频繁使用的正则应定义为常量
- 限制匹配长度:避免对超长字符串进行复杂匹配
- 使用最新API:优先使用
matchAll()替代exec()循环
四、常见错误与注意事项
- 过度依赖正则:对于嵌套结构(如HTML、JSON),应优先使用专用解析器而非正则
- 安全风险:用户输入的正则需进行转义,防止ReDoS攻击
javascript
// 安全转义用户输入
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
- 校验层级:应实施多层次校验
- 前端校验:提升用户体验
- 后端校验:确保业务安全
- 数据库约束:最后一道防线
- 正则可读性:复杂正则应添加注释说明
javascript
const complexReg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; // YYYY-MM-DD格式