本文适合前端初学者、日常开发使用及面试复习,从正则基础到实战场景,全程可直接复制运行
前言
正则表达式(Regular Expression,简称 RegExp)是前端开发中处理字符串的核心利器,无论是表单校验、字符串格式转换、关键词提取、文本分割,还是数据清洗,都离不开正则表达式。相比于传统的循环遍历、字符截取等方式,正则用一套简洁的符号规则,实现高效、优雅的字符串操作。
本文将从正则基础语法讲起,结合连字符转驼峰命名 、手机号严格校验两大实战场景,深度解析代码逻辑,并补充面试高频实操题,帮助你彻底掌握正则表达式。
一、正则表达式核心基础语法
正则表达式由字面量字符、元字符、字符类、量词、边界、分组、修饰符七大部分组成,是匹配字符串的规则集合。
1. 字面量字符
字面量字符是正则中最基础、无特殊含义的字符,直接匹配自身。
- 示例:正则
/abc/可匹配字符串中连续的abc。 - 特点:大小写敏感,无特殊语义,仅做精准匹配。
2. 元字符
元字符是正则中具备特殊功能的符号,是正则的核心,不能直接匹配自身,需转义后才能匹配。
常用元字符:
.:匹配任意单个字符(换行符除外)*:匹配前一个字符 0 次或多次+:匹配前一个字符 1 次或多次(贪婪匹配)?:匹配前一个字符 0 次或 1 次- ``:转义符,将元字符转为字面量(如匹配
.需写.)
3. 字符类
字符类用于匹配某一类特定字符,是正则中最常用的匹配规则。
表格
| 字符 | 匹配范围 | 等价写法 | 示例 |
|---|---|---|---|
\d |
任意数字 | [0-9] |
/\d/.test('5') → true |
\D |
非数字 | [^0-9] |
/\D/.test('a') → true |
\w |
字母、数字、下划线 | [a-zA-Z0-9_] |
/\w/.test('_') → true |
\W |
非字母 / 数字 / 下划线 | [^a-zA-Z0-9_] |
/\W/.test('-') → true |
\s |
空白字符(空格、tab、换行) | - | /\s/.test(' ') → true |
\S |
非空白字符 | - | /\S/.test('a') → true |
[] |
字符组合,匹配任意一个 | - | /[a,b]/.test('a') → true |
4. 量词
量词用于限定字符的匹配次数,精准控制匹配长度。
表格
| 量词 | 含义 | 示例 |
|---|---|---|
{n} |
恰好匹配 n 次 | /\d{3}/ 匹配 3 位数字 |
{n,} |
匹配 n 次及以上 | /\d{2,}/ 匹配 2 位及以上数字 |
{n,m} |
匹配 n~m 次 | /\d{2,4}/ 匹配 2-4 位数字 |
+ |
1 次及以上(等价 {1,}) |
/\d+/ 匹配任意长度数字 |
* |
0 次及以上(等价 {0,}) |
/\w*/ 匹配 0 个及以上单词字符 |
? |
0 次或 1 次(等价 {0,1}) |
/\d?/ 匹配 0 个或 1 个数字 |
5. 边界符
边界符用于限定匹配的位置,避免非目标内容干扰,是严格校验的关键。
^:匹配字符串开头$:匹配字符串结尾\b:匹配单词边界(如单词与空格的交界处)
6. 分组
分组用 () 实现,核心作用是捕获匹配的子内容,方便后续提取或替换。
- 捕获分组:
(\w)匹配并捕获内容,可通过$1、$2或回调参数获取 - 非捕获分组:
(?:\w)仅匹配不捕获,减少性能开销
7. 修饰符
修饰符写在正则末尾,全局控制匹配规则。
g:全局匹配,匹配所有符合规则的内容(而非仅第一个)i:忽略大小写m:多行匹配,按行匹配^和$
8. 正则核心方法
正则的使用离不开字符串和正则对象的方法,常用方法如下:
1)RegExp.prototype.test()
- 作用:检测字符串是否匹配正则规则
- 返回值:布尔值(
true/false) - 示例:
/^1\d{10}$/.test('15766668888') → true
2)String.prototype.match()
- 作用:提取字符串中匹配正则的内容
- 返回值:匹配成功返回数组,失败返回
null - 示例:
'价格10880元'.match(/\d+/) → ['10880']
3)String.prototype.replace()
- 作用:替换匹配正则的内容,支持字符串 / 回调函数
- 示例:
'a-b-c'.replace(/-(\w)/g, (_, c) => c.toUpperCase()) → 'aBC'
4)String.prototype.split()
- 作用:按正则规则分割字符串
- 示例:
'a,b c'.split(/[,\s]+/) → ['a','b','c']
二、实战场景一:连字符命名转驼峰命名
1. 需求说明
开发中常遇到 adb-cdf、-qwe-try 这类连字符命名,需转换为驼峰命名 adbCdf、qweTry,要求:
- 去除开头的连字符
- 连字符后的第一个字母转为大写
- 支持全局替换所有连字符片段
2. 正则规则设计
核心正则:/-(\w)/g
-:匹配连字符字面量(\w):分组捕获连字符后的字母 / 数字 / 下划线g:全局修饰符,匹配所有连字符片段
3. 完整代码实现
javascript
/**
* 连字符命名转驼峰命名
* @param {string} str - 待转换的连字符字符串
* @returns {string} 驼峰命名字符串
*/
function toCamelCase(str) {
// 第一步:去除字符串开头的所有连字符
let result = str.replace(/^-+/, '');
// 第二步:全局匹配 "-字符",将捕获的字符转大写
result = result.replace(/-(\w)/g, (match, char) => {
// match:完整匹配的片段(如 -c)
// char:分组捕获的字符(如 c)
return char.toUpperCase();
});
return result;
}
// 测试用例
console.log(toCamelCase('adb-cdf')); // adbCdf
console.log(toCamelCase('-qwe-try')); // qweTry
console.log(toCamelCase('background-color')); // backgroundColor
console.log(toCamelCase('-webkit-animation-name')); // webkitAnimationName
4. 代码解析
- 第一步
/^-+/:匹配开头 1 个及以上连字符,替换为空,解决开头符号问题 - 第二步
/-(\w)/g:全局匹配所有连字符 + 字符组合,通过回调函数将字符转大写 - 回调参数:第一个参数是完整匹配内容,第二个是分组捕获内容,无需完整匹配时可用
_占位
三、实战场景二:手机号格式严格校验
1. 需求说明
为保证后端数据准确性,需严格校验手机号:
- 必须是 11 位数字
- 以数字
1开头 - 无任何多余字符(字母、空格、符号)
2. 正则规则设计
核心正则:/^1\d{10}$/
^:限定字符串开头,确保从第一个字符开始匹配1:匹配手机号开头的数字 1\d{10}:匹配后续 10 位数字,精准控制总长度为 11 位$:限定字符串结尾,确保无多余字符
3. 完整代码实现
javascript
// 正则常量复用:仅创建一次正则实例,提升性能
const PHONE_REGEX = /^1\d{10}$/;
/**
* 手机号格式校验
* @param {string} phone - 待校验的手机号
* @returns {boolean} 合法返回 true,否则返回 false
*/
function validatePhone(phone) {
// 类型校验:排除非字符串输入
if (typeof phone !== 'string') return false;
// 正则校验
return PHONE_REGEX.test(phone);
}
// 测试用例
console.log(validatePhone('15766668888')); // true(合法)
console.log(validatePhone('d15766668888')); // false(含字母)
console.log(validatePhone('1576666888')); // false(长度不足)
console.log(validatePhone('25766668888')); // false(非 1 开头)
console.log(validatePhone('15766668888 ')); // false(含空格)
4. 关键知识点:正则常量复用
正则常量复用 :将固定不变的正则表达式,用 const 定义在函数外部,仅创建一次正则实例,函数多次调用时复用该实例。
- 优势:避免函数每次调用都重新创建正则对象,减少性能开销
- 适用场景:规则固定的正则(如手机号、邮箱校验)
- 反例:正则写在函数内部,每次调用都新建实例,造成资源浪费
四、面试高频实操题(含答案)
1. 基础面试题
题目 1:\w 和 \W 的区别?
答案:
\w:匹配字母(大小写)、数字、下划线\W:\w的取反,匹配非字母、数字、下划线的字符(如空格、符号、中文)
题目 2:正则中 ^ 和 $ 的作用?
答案:
^:匹配字符串开头,防止开头出现多余字符$:匹配字符串结尾,防止结尾出现多余字符- 两者结合可实现严格全匹配,是表单校验的核心
题目 3:+ 和 * 的区别?
答案:
+:匹配前一个字符 1 次或多次,至少匹配 1 次*:匹配前一个字符 0 次或多次,可以匹配 0 次
2. 实操面试题
题目 1:实现下划线 + 连字符混合命名转驼峰
如 hello_world-test → helloWorldTest
javascript
function mixToCamel(str) {
let result = str.replace(/^[-_]+/, '');
result = result.replace(/[-_](sslocal://flow/file_open?url=%5Cw&flow_extra=eyJsaW5rX3R5cGUiOiJjb2RlX2ludGVycHJldGVyIn0=)/g, (_, c) => c.toUpperCase());
return result;
}
console.log(mixToCamel('hello_world-test')); // helloWorldTest
题目 2:支持带分隔符的手机号校验
如 157-6666-8888、157 6666 8888
、
javascript
function validatePhoneWithSymbol(phone) {
if (typeof phone !== 'string') return false;
// 先去除所有非数字字符
const purePhone = phone.replace(/\D/g, '');
return /^1\d{10}$/.test(purePhone);
}
console.log(validatePhoneWithSymbol('157-6666-8888')); // true
题目 3:提取字符串中所有数字
如 价格100元,折扣8折 → ['100','8']
javascript
function getAllNumbers(str) {
return str.match(/\d+/g) || [];
}
console.log(getAllNumbers('价格100元,折扣8折')); // ['100','8']
题目 4:用正则分割字符串(按逗号、空格、分号分割)
javascript
function splitString(str) {
return str.split(/[,\s;]+/);
}
console.log(splitString('apple,banana orange;pear')); // ['apple','banana','orange','pear']
五、总结
- 正则是前端字符串处理的核心工具,掌握字符类、量词、边界、分组、修饰符五大核心,即可应对 90% 的场景
- 实战中,连字符转驼峰 用
/-(\w)/g全局替换,手机号校验 用/^1\d{10}$/严格匹配 - 性能优化:固定规则的正则采用常量复用,避免重复创建实例
- 面试重点:分组捕获、边界符、全局修饰符、正则复用、实战转换 / 校验
熟练运用正则,能让你的字符串代码更简洁、高效,是前端工程师必备的核心技能。