在 Java Web 项目里摸爬滚打一段时间后,你会慢慢发现,前端表单校验、数据提取、字符串替换这些看似琐碎的活儿,写起来最费神的往往不是业务逻辑,而是怎么把一段字符串"收拾"得服服帖帖。JavaScript 中的正则表达式(RegExp)就是干这个的,它是处理字符串的一套独立语法体系,也是 JS 中少有的"学起来费劲、用起来真香"的知识点。这一篇我打算把正则表达式这件事讲透,从基础语法到 Java Web 项目里的真实场景,一次聊明白。
这玩意儿到底解决什么问题?打个比方,字符串就像一整块面团,正则就是一套刻好的模具,你想把面团压成什么形状,直接拿模具往上一扣就行。比如你要判断用户输入的手机号是否合法、从一大段 HTML 里抽出所有图片地址、把富文本里的敏感词替换掉,这些"按规则找内容"的需求,正则都能干。所以说,正则不是 JS 独有的,但 JS 里的正则用法和 Java 后端岗位的匹配度非常高,尤其是前后端联调时,前端做一次预校验、后端再做一次安全校验,两端语法虽然略有差异,核心逻辑却一致,学懂 JS 正则在 Java Web 开发中是必须跨过去的一道坎。
这篇文章适合谁?初学者可以把它当成入门指南,有基础的人也能从后边的案例和排错里找到点平时没留意的东西。我尽量把语法拆开揉碎,配上能直接跑起来的例子,读完之后你至少能独立写出常用的表单校验、数据提取和文本替换正则。好了,废话不多说,直接进入正题。
1. 正则表达式到底是什么:别把它想复杂了
1.1 核心概念:一种"字符串匹配规则"
正则表达式(Regular Expression,简称 regex、regexp 或 RE)本质上是一种描述字符串结构的表达式。它用一堆特殊符号组成"规则",然后拿着这个规则去字符串里寻找符合要求的子串。你可以把它理解成一种极其精简的"搜索条件"。
我先说几个最简单直观的规则:
abc:精确匹配字符串里的 "abc" 这三个连续字符[0-9]:匹配任意一个数字字符[a-z]:匹配任意一个小写字母.:匹配除了换行符以外的任意单个字符\d:匹配任意一个数字,等价于[0-9]\w:匹配字母、数字、下划线,等价于[A-Za-z0-9_]\s:匹配空白字符(空格、制表符、换行等)
举个例子,规则 \d{11} 的意思是"11 个连续的数字",用它可以去字符串里找手机号。规则 \w+@\w+\.\w+ 的意思就复杂一些了,它描述了一个简易邮箱的形态:字母数字下划线组成的字符串 + @ + 字母数字下划线 + 点 + 字母数字下划线。
看到这里你可能会觉得,这跟普通的字符串查找(比如 indexOf)有什么区别?区别大了。indexOf 查找的是"死的字符串",你告诉它找 "abc",它就只找 "abc";而正则找的是"活的规则",你可以告诉它"找一个以字母开头、后面跟着 5~8 个数字、结尾不能是 0 的字符串",这种复杂需求用普通字符串方法是没法表达的。
1.2 正则表达式的组成结构
一个完整的正则表达式通常包含三部分:普通字符、元字符和修饰符。
- 普通字符:就是字面意思,比如
a、b、1、你,它们匹配自身 - 元字符:有特殊含义的符号,比如
\d、\w、^、$、*、+、?、[]、()、{}、|等 - 修饰符:写在正则末尾的标志位,比如
i(忽略大小写)、g(全局匹配)、m(多行匹配)
你可以把正则当成一门"小语言",普通字符是它的单词,元字符是它的语法,修饰符是它的运行参数。学会正则的过程,就是熟悉这套语法的过程,不用背,多写几次自然就记住了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. JavaScript 中正则的两种写法与 RegExp 对象
2.1 字面量与构造函数,两种创建方式
在 JavaScript 里,创建正则有两种方式,先记结论:能用字面量就用字面量。
javascript复制// 方式一:字面量(推荐)
const reg1 = /\d{11}/;
// 方式二:构造函数
const reg2 = new RegExp("\\d{11}");
这两种方式有一个关键区别:字面量里的 \ 就是正则自身的转义符,所以 \d 直接写;而构造函数接收的是字符串,字符串里的 \ 需要先转义成 \\,最终 RegExp 内部收到的才是 \d。这就是为什么 new RegExp("\\d{11}") 要写两个反斜杠。
构造函数的好处在于规则本身可以动态拼接。比如你要根据用户选择的校验类型动态生成正则,那就得用构造函数:
javascript复制let type = "email"; // 这个值可能是动态的
let pattern = type === "email" ? "^\\w+@\\w+\\.\\w+$" : "^\\d{11}$";
let reg = new RegExp(pattern);
但在固定规则场景下,字面量更直观,也避免了字符串转义的坑,性能上通常也更好一些(正则引擎在脚本加载时就会完成编译)。
2.2 RegExp 实例方法:test 和 exec 的差别
RegExp 对象上有两个核心方法:test() 和 exec()。
test() 返回布尔值,用来判断字符串是否符合正则规则,这是表单校验里用得最多的:
javascript复制const reg = /^\d{11}$/;
console.log(reg.test("13812345678")); // true
console.log(reg.test("1381234567")); // false
console.log(reg.test("13812345678a")); // false
exec() 则更进一步,它返回一个数组,包含匹配到的字符串以及捕获组的内容,适合做数据提取:
javascript复制const reg = /(\d{3})-(\d{8})/;
const result = reg.exec("联系电话:010-12345678");
console.log(result[0]); // "010-12345678"
console.log(result[1]); // "010"
console.log(result[2]); // "12345678"
这里要注意,exec() 返回的数组里,第 0 项是完整匹配的字符串,第 1 项及之后是捕获组的内容(后面讲分组时会细说)。
2.3 字符串方法中的正则应用
除了 RegExp 对象自带的方法,字符串本身也有几个方法可以配合正则使用,这个在实际开发中更常用,得重点掌握。
javascript复制const str = "Hello World, welcome to Java Web!";
// 1. match():返回匹配结果数组
const
