当前位置: 首页 > news >正文

JavaScript 正则表达式全方位解析:从基础到实战

正则表达式(Regular Expression,简称 Regex)是处理字符串的强大工具,它通过特定语法规则匹配、查找、替换字符串中的目标内容,广泛应用于表单验证、数据提取、格式清洗等场景。

一、正则表达式基础概念

1. 核心定义

正则表达式是描述字符串匹配模式的字符序列,本质是 “规则模板”,用于:

  • 验证字符串格式(如手机号、邮箱、身份证号);
  • 提取字符串中的目标内容(如从 URL 中提取参数);
  • 替换字符串中的特定字符(如敏感词过滤)。

2. 正则表达式的特点

  • 灵活性:一行正则可替代数十行字符串判断代码;
  • 高效性:浏览器原生支持,匹配效率高于手动字符串遍历;
  • 通用性:语法在 JavaScript、Java、Python 等语言中高度一致,学会后可跨语言复用。

二、正则表达式的两种创建方式

JavaScript 中创建正则表达式有两种方式:字面量模式和构造函数模式,适用于不同场景。

1. 字面量模式(推荐,简单场景)

/正则内容/修饰符表示,直接嵌入代码,无需转义过多字符。

代码示例

javascript

// 1. 匹配字符串中的 "hello"(无修饰符)
const reg1 = /hello/;
console.log(reg1); // /hello/// 2. 匹配 "hello",忽略大小写(i 修饰符)
const reg2 = /hello/i;
console.log(reg2); // /hello/i// 3. 全局匹配 "hello"(g 修饰符)
const reg3 = /hello/g;
console.log(reg3); // /hello/g// 4. 多修饰符组合(全局匹配+忽略大小写)
const reg4 = /hello/gi;
console.log(reg4); // /hello/gi
注意事项
  • 字面量中不能使用变量,若需动态拼接正则,需用构造函数模式;
  • 特殊字符(如/\)需转义,例如匹配/需写为\/

2. 构造函数模式(动态场景)

通过new RegExp(正则字符串, 修饰符)创建,支持动态传入正则规则(如变量拼接)。

代码示例

javascript

// 1. 基础构造(匹配 "hello",无修饰符)
const reg1 = new RegExp("hello");
console.log(reg1); // /hello/// 2. 带修饰符(全局匹配+忽略大小写)
const reg2 = new RegExp("hello", "gi");
console.log(reg2); // /hello/gi// 3. 动态拼接正则(例如从变量获取匹配内容)
const matchStr = "hello";
const reg3 = new RegExp(matchStr, "i"); // 动态传入匹配字符串
console.log(reg3.test("Hello World")); // true(忽略大小写匹配)// 4. 特殊字符转义(构造函数中需双重转义,因为字符串本身需转义)
const reg4 = new RegExp("\\d+"); // 匹配数字(等同于 /\d+/)
console.log(reg4.test("123")); // true
核心区别
特性字面量模式构造函数模式
语法格式/pattern/flagsnew RegExp(pattern, flags)
动态拼接不支持支持(参数可传变量)
特殊字符转义单重转义(如\/双重转义(如\\/
性能稍高(解析时编译)稍低(运行时编译)

三、正则表达式核心语法(必掌握)

正则的强大之处在于其灵活的语法规则,分为字符分类、边界符、量词、分组、前瞻断言五大类,以下是高频语法的详细讲解。

1. 字符分类:匹配特定类型的字符

用于匹配某一类字符(如数字、字母、空格),是正则的基础组成部分。

语法描述示例匹配结果
[abc]匹配 a、b、c 中的任意一个字符/[abc]/匹配 "a"、"b"、"c"
[a-z]匹配小写字母 a-z/[a-z]/匹配 "x"、"y"(小写字母)
[A-Z]匹配大写字母 A-Z/[A-Z]/匹配 "X"、"Y"(大写字母)
[0-9]匹配数字 0-9/[0-9]/匹配 "1"、"2"(数字)
\d等同于 [0-9](数字)/\d/匹配 "5"、"6"
\D等同于 [^0-9](非数字)/\D/匹配 "a"、"!"(非数字)
\w匹配字母、数字、下划线([a-zA-Z0-9_]/\w/匹配 "a"、"5"、"_"
\W匹配非字母、数字、下划线/\W/匹配 "!"、"@"、" "
\s匹配空白字符(空格、制表符、换行)/\s/匹配 ""、"\t"、"\n"
\S匹配非空白字符/\S/匹配 "a"、"1"、"!"
.匹配除换行符(\n)外的任意字符/./匹配 "a"、"1"、"!"
代码示例

javascript

const str = "Hello 123!_";// 1. 匹配数字(\d)
const reg1 = /\d/;
console.log(reg1.test(str)); // true(字符串含 "123")// 2. 匹配非数字(\D)
const reg2 = /\D/;
console.log(reg2.test(str)); // true(字符串含 "Hello"、"!"、"_")// 3. 匹配空白字符(\s)
const reg3 = /\s/;
console.log(reg3.test(str)); // true("Hello" 和 "123" 之间有空格)// 4. 匹配任意字符(.)
const reg4 = /./;
console.log(reg4.test(str)); // true(匹配任意非换行字符)

2. 边界符:限定匹配的位置

用于限定目标字符在字符串中的位置(如开头、结尾、单词边界),避免部分匹配。

语法描述示例匹配结果
^匹配字符串开头/^hello/匹配 "helloWorld"(开头是 hello)
$匹配字符串结尾/world$/匹配 "helloWorld"(结尾是 world)
\b匹配单词边界(单词与非单词之间)/\bhello\b/匹配 "hello world"(独立的 hello)
\B匹配非单词边界/\Bhello\B/匹配 "ahellob"(hello 前后非单词边界)
代码示例

javascript

const str1 = "hello world";
const str2 = "helloworld";// 1. 匹配开头为 "hello"(^)
const reg1 = /^hello/;
console.log(reg1.test(str1)); // true(str1 开头是 hello)
console.log(reg1.test(str2)); // true(str2 开头是 hello)// 2. 匹配结尾为 "world"($)
const reg2 = /world$/;
console.log(reg2.test(str1)); // true(str1 结尾是 world)
console.log(reg2.test(str2)); // true(str2 结尾是 world)// 3. 匹配独立的 "hello"(\b)
const reg3 = /\bhello\b/;
console.log(reg3.test(str1)); // true(str1 中 hello 是独立单词)
console.log(reg3.test(str2)); // false(str2 中 hello 与 world 连在一起,无单词边界)
关键实战:精确匹配

用 ^ 和 $ 组合实现 “精确匹配”(字符串必须完全符合正则规则),常用于表单验证:

javascript

// 精确匹配 6 位数字(如验证码)
const reg = /^\d{6}$/;
console.log(reg.test("123456")); // true(完全匹配 6 位数字)
console.log(reg.test("12345"));  // false(不足 6 位)
console.log(reg.test("12345a")); // false(含非数字字符)

3. 量词:限定字符出现的次数

用于控制目标字符的出现次数(如 “至少 1 次”“最多 3 次”“恰好 2 次”),是正则简化代码的核心。

语法描述示例匹配结果
*匹配前面的字符 0 次或多次/a*/匹配 ""、"a"、"aa"
+匹配前面的字符 1 次或多次/a+/匹配 "a"、"aa"(不匹配 "")
?匹配前面的字符 0 次或 1 次/a?/匹配 ""、"a"(不匹配"aa")
{n}匹配前面的字符恰好 n 次/a{2}/匹配 "aa"(不匹配 "a"、"aaa")
{n,}匹配前面的字符至少 n 次/a{2,}/匹配 "aa"、"aaa"
{n,m}匹配前面的字符 n 到 m 次/a{2,3}/匹配 "aa"、"aaa"(不匹配 "a"、"aaaa")
代码示例

javascript

const str = "aaabbb";// 1. 匹配 a 至少 2 次(a{2,})
const reg1 = /a{2,}/;
console.log(reg1.test(str)); // true(str 含 "aaa",满足至少 2 次)// 2. 匹配 b 恰好 3 次(b{3})
const reg2 = /b{3}/;
console.log(reg2.test(str)); // true(str 含 "bbb",恰好 3 次)// 3. 匹配 a 0 次或 1 次(a?)
const reg3 = /a?/;
console.log(reg3.test(""));  // true(0 次)
console.log(reg3.test("a")); // true(1 次)
console.log(reg3.test("aa"));// true(但仅匹配第一个 a)// 4. 匹配 a 0 次或多次(a*)
const reg4 = /a*/;
console.log(reg4.test(""));  // true(0 次)
console.log(reg4.test("aaa"));// true(3 次)
关键实战:贪婪与非贪婪模式

量词默认是贪婪模式(尽可能多匹配),在量词后加 ? 可变为非贪婪模式(尽可能少匹配):

javascript

const str = "aaaaa";// 贪婪模式(匹配最多 3 个 a)
const reg1 = /a{2,3}/;
console.log(str.match(reg1)); // ["aaa"](贪婪匹配,取 3 个 a)// 非贪婪模式(匹配最少 2 个 a)
const reg2 = /a{2,3}?/;
console.log(str.match(reg2)); // ["aa"](非贪婪匹配,取 2 个 a)

4. 分组与引用:批量匹配与复用

用 () 实现分组,将多个字符视为一个整体,支持批量匹配和结果引用。

4.1 分组匹配(批量控制)

javascript

// 匹配 "ab" 重复 2 次(分组后用 {2} 控制)
const reg = /(ab){2}/;
console.log(reg.test("abab")); // true("ab" 重复 2 次)
console.log(reg.test("ab"));  // false(仅 1 次)
4.2 分组引用(复用匹配结果)

用 \n(n 为分组序号)引用之前分组的匹配结果,常用于匹配重复内容:

javascript

// 匹配前后相同的单词(如 "hello hello")
const reg = /(\w+)\s+\1/;
console.log(reg.test("hello hello")); // true(\1 引用第一个分组的 "hello")
console.log(reg.test("hello world")); // false(前后单词不同)// 提取分组结果(通过 exec 或 match 获取)
const str = "hello hello";
const result = reg.exec(str);
console.log(result[1]); // "hello"(第一个分组的结果)
4.3 选择符(或逻辑)

用 | 实现 “或” 逻辑,匹配多个模式中的任意一个:

javascript

// 匹配 "hello" 或 "world"
const reg = /hello|world/;
console.log(reg.test("hello")); // true
console.log(reg.test("world")); // true
console.log(reg.test("hi"));    // false

5. 前瞻断言:匹配的 “附加条件”

前瞻断言用于判断目标字符 “后面是否满足某个条件”,不消耗字符本身,仅作为匹配的附加规则。

语法描述示例匹配结果
(?=exp)正向前瞻:后面必须满足 exp/a(?=b)/匹配 "ab" 中的 "a"(后面是 b)
(?!exp)负向前瞻:后面必须不满足 exp/a(?!b)/匹配 "ac" 中的 "a"(后面不是 b)
代码示例

javascript

const str = "ab ac ad";// 1. 正向前瞻:匹配后面是 "b" 的 "a"
const reg1 = /a(?=b)/g;
console.log(str.match(reg1)); // ["a"](仅匹配 "ab" 中的 "a")// 2. 负向前瞻:匹配后面不是 "b" 的 "a"
const reg2 = /a(?!b)/g;
console.log(str.match(reg2)); // ["a", "a"](匹配 "ac"、"ad" 中的 "a")
实战场景:密码强度验证

用前瞻断言实现 “密码必须包含大小写字母、数字、特殊字符”:

javascript

// 密码强度验证:8-16位,含大小写字母、数字、特殊字符(!@#$%^&*)
const reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])[a-zA-Z\d!@#$%^&*]{8,16}$/;
console.log(reg.test("Abc123!@#")); // true(满足所有条件)
console.log(reg.test("abc123!@#")); // false(无大写字母)
console.log(reg.test("Abcdefgh"));  // false(无数字和特殊字符)

四、正则表达式实例方法(核心操作)

正则表达式对象提供了 4 个常用实例方法,用于匹配、验证、转换字符串,其中 test 和 exec 是高频方法。

1. test():验证是否匹配(返回布尔值)

判断字符串中是否存在匹配正则的内容,返回 true(存在)或 false(不存在),常用于表单验证。

代码示例

javascript

// 验证手机号(11位数字,以 13/14/15/17/18 开头)
const phoneReg = /^1[34578]\d{9}$/;
const phone1 = "13812345678";
const phone2 = "12345678901";console.log(phoneReg.test(phone1)); // true(符合手机号规则)
console.log(phoneReg.test(phone2)); // false(开头不是 13/14/15/17/18)

2. exec():获取匹配详情(返回数组或 null)

返回字符串中匹配正则的详细信息(如匹配内容、位置),若无匹配则返回 null

代码示例

javascript

const str = "Hello World Hello JavaScript";
const reg = /Hello/g; // 全局匹配// 第一次执行 exec
let result1 = reg.exec(str);
console.log(result1); 
// 输出:["Hello", index: 0, input: "Hello World Hello JavaScript", groups: undefined]// 第二次执行 exec(全局匹配,从 lastIndex 继续)
let result2 = reg.exec(str);
console.log(result2);
// 输出:["Hello", index: 12, input: "Hello World Hello JavaScript", groups: undefined]// 第三次执行 exec(无更多匹配,返回 null)
let result3 = reg.exec(str);
console.log(result3); // null
关键注意点
  • 若正则有 g(全局)修饰符,exec 会维护 lastIndex 属性,记录下一次匹配的起始位置;
  • 若正则无 g 修饰符,每次 exec 都会从字符串开头重新匹配。

3. toString()/toLocaleString():转为字面量字符串

将正则对象转为字面量形式的字符串(如 /hello/),两者在 JavaScript 中功能一致。

代码示例

javascript

const reg = /hello/gi;
console.log(reg.toString()); // "/hello/gi"
console.log(reg.toLocaleString()); // "/hello/gi"

4. valueOf():返回正则本身

返回正则对象的原始值(即正则本身),一般用于确认正则的引用。

代码示例

javascript

const reg = /hello/;
console.log(reg.valueOf()); // /hello/
console.log(reg.valueOf() === reg); // true

五、String 对象的正则方法(字符串视角)

除了正则实例方法,String 对象也提供了 4 个支持正则的方法,从字符串视角操作正则。

1. match():获取所有匹配结果

返回字符串中所有匹配正则的内容,若正则有 g 修饰符则返回数组,否则返回详细匹配信息。

代码示例

javascript

const str = "Hello World Hello JavaScript";// 1. 无 g 修饰符(返回详细信息)
const reg1 = /Hello/;
console.log(str.match(reg1));
// 输出:["Hello", index: 0, input: "Hello World Hello JavaScript", groups: undefined]// 2. 有 g 修饰符(返回所有匹配结果)
const reg2 = /Hello/g;
console.log(str.match(reg2)); // ["Hello", "Hello"]

2. search():获取首次匹配位置

返回字符串中首次匹配正则的起始索引,若无匹配则返回 -1,忽略 g 修饰符。

代码示例

javascript

const str = "Hello World Hello JavaScript";
const reg = /World/;
console.log(str.search(reg)); // 6("World" 从索引 6 开始)
console.log(str.search(/Java/)); // 17("Java" 从索引 17 开始)
console.log(str.search(/Hi/)); // -1(无匹配)

3. replace():替换匹配内容

替换字符串中匹配正则的内容,返回新字符串(不修改原字符串),支持全局替换。

代码示例

javascript

运行

const str = "Hello World Hello JavaScript";// 1. 替换第一个 "Hello" 为 "Hi"(无 g 修饰符)
const reg1 = /Hello/;
console.log(str.replace(reg1, "Hi")); // "Hi World Hello JavaScript"// 2. 全局替换 "Hello" 为 "Hi"(有 g 修饰符)
const reg2 = /Hello/g;
console.log(str.replace(reg2, "Hi")); // "Hi World Hi JavaScript"// 3. 替换敏感词(* 替换)
const badWordReg = /敏感词/g;
console.log("这是敏感词,不能显示".replace(badWordReg, "***")); // "这是***,不能显示"

4. split():按正则分割字符串

按正则匹配的内容分割字符串,返回分割后的数组,支持复杂分割规则。

代码示例

javascript

运行

const str = "terry134briup156lisi12zhangsan";// 按 1 个或多个数字分割
const reg = /\d+/;
console.log(str.split(reg)); // ["terry", "briup", "lisi", "zhangsan"]// 按 "Hello" 或 "World" 分割
const str2 = "Hello123World456Hello789";
const reg2 = /Hello|World/;
console.log(str2.split(reg2)); // ["", "123", "456", "789"]

六、正则表达式实战案例(必看)

结合实际开发场景,用正则解决常见问题,巩固前面所学知识点。

1. 案例 1:验证邮箱格式

邮箱规则:包含 @ 和 .@ 前为字母 / 数字 / 下划线,@ 后为域名(如 qq.comgmail.com)。

javascript

const emailReg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
console.log(emailReg.test("123@qq.com")); // true
console.log(emailReg.test("abc-123@gmail.com")); // true
console.log(emailReg.test("abc@.com")); // false(@ 后无域名)
console.log(emailReg.test("abc@com")); // false(无 . 分隔域名)

2. 案例 2:提取 URL 中的参数

从 URL(如 https://www.baidu.com?name=tom&age=18)中提取参数,返回参数对象。

javascript

function getUrlParams(url) {const params = {};// 匹配 ? 后的参数(如 name=tom&age=18)const reg = /\?([^#]+)/;const paramStr = url.match(reg)[1]; // "name=tom&age=18"// 分割参数为数组(如 ["name=tom", "age=18"])const paramArr = paramStr.split("&");// 遍历数组,提取键值对paramArr.forEach(item => {const [key, value] = item.split("=");params[key] = decodeURIComponent(value); // 解码(处理中文等特殊字符)});return params;
}const url = "https://www.baidu.com?name=tom&age=18&city=%E5%8C%97%E4%BA%AC";
console.log(getUrlParams(url));
// 输出:{ name: "tom", age: "18", city: "北京" }

3. 案例 3:格式化手机号(中间 4 位打码)

将手机号 13812345678 格式化为 138****5678

javascript

const phoneReg = /(\d{3})\d{4}(\d{4})/;
const phone = "13812345678";
const formattedPhone = phone.replace(phoneReg, "$1****$2");
console.log(formattedPhone); // "138****5678"

七、正则表达式避坑指南

  1. 特殊字符转义:正则中的特殊字符(如 .*?)需用 \ 转义,例如匹配 . 需写为 \.
  2. 全局匹配的 lastIndex 问题:用 exec 或 test 时,若正则有 g 修饰符,多次调用会从 lastIndex 继续,如需重新匹配,需手动重置 lastIndex = 0
  3. 贪婪模式的意外匹配:量词默认贪婪,如需最小匹配,需在量词后加 ?(如 {2,3}?);
  4. 换行符的匹配. 不匹配换行符(\n),如需匹配所有字符,需用 [\s\S] 或 [\d\D]

总结

正则表达式是 JavaScript 中处理字符串的 “瑞士军刀”,掌握其语法规则和方法后,能极大提升字符串处理效率。本文从基础到实战,覆盖了正则的核心知识点,建议重点掌握:

  • 常用语法:\d(数字)、{n,m}(量词)、^$(边界)、()(分组);
  • 高频方法:test(验证)、exec(详情)、replace(替换);
  • 实战场景:表单验证、数据提取、格式清洗。
http://www.dtcms.com/a/573232.html

相关文章:

  • 工业相机成像核心参数解析,帧率与曝光时间的权衡关系
  • Kodiak Perps:Berachain 原生永续合约平台上线
  • 分布式版本控制系统Git的安装和使用
  • 用.echarts文件快速实现日历饼图
  • 影刀RPA一键生成竞品分析!AI智能监控,效率提升100倍[特殊字符]
  • 从卡顿到秒查:Java 项目引入 Elasticsearch 实现亿级地址数据的复杂查询实战
  • 国外可以做推广的网站有哪些广州品牌形象设计
  • 【MySQL】SQL语法详细总结
  • 宿迁华夏建设集团网站下列什么软件不能用于设计网页
  • vue笔记(第一天)
  • cursor和传统idea的区别是什么?
  • SSM--MyBatis框架SQL映射文件获取一对一或者一对多关系值
  • 网站开发实验报告总结阿里云是不是做网站的
  • 1000元级投影选哪款?大眼橙C3D实测体验闭眼入
  • 第一章 函数与极限 2.数列的极限
  • 用ps网站首页怎么做做a免费网站有哪些
  • 多因子量化模型预警:美元强势因子压制金价失守4000关口,ADP数据能否重构黄金趋势?
  • Mac 安装 Xcode 及qt 环境安装
  • AS2协议的实时性:重构制造业供应链协同效率
  • 城乡建设部官网查证助孕网站优化推广
  • leetcode17.电话号码的数字组合(题目详解)
  • C# WebAPI Swagger如何显示接口注释
  • 三网站建设装修公司做网站有用吗
  • 怎么做谷歌收录的网站个人接广告的平台
  • Unity坐标转换指南 - 3D与屏幕UI坐标互转
  • Admin界面优化:移除可用区字段以简化显示
  • Java 位运算算法题目练习
  • 企业定制手机安全加固:数据加密、权限管控与防泄密功能解析
  • opencv 计算面积、周长
  • 静态网站设计方案二维码设计软件