主题
2-18正则表达式和元字符(一)
本页对应 第二章WebAPIs,共 5 段视频,约 1 小时 3 分。
学习目标
- 能说明正则表达式是一种字符串匹配规则,并列举表单验证、敏感词替换、字符串提取等典型使用场景。
- 能使用字面量
/规则/定义正则,并用test()检测字符串是否匹配,正确解释返回的布尔值。 - 能使用边界符
^、$完成开头匹配、结尾匹配和精确匹配,并判断给定字符串的匹配结果。 - 能使用量词
*、+、?、{n}、{n,}、{n,m}控制重复次数,并指出逗号两侧不能出现空格。 - 能使用字符范围
[]、连字符-、取反符^构造匹配规则,并结合量词写出用户名验证正则。 - 能实现用户名表单失去焦点验证案例:根据正则匹配结果切换
right/wrong类名,并显示或隐藏错误提示框。
知识点
为什么需要 replace
正则表达式本质上是一种“规则”,用来判断字符串是否符合某种模式,也可以用来查找、提取和替换字符串中的内容。转写稿里提到,敏感词过滤的典型做法就是先定义规则,再把命中的敏感词替换成星星等内容。这里真正完成“替换动作”的方法,就是字符串的 replace。
本节的需求很明确:把下面这句话里的“前端”替换成“web”。
js
const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神'如果不使用替换方法,只靠手工查找和拼接,代码会非常麻烦。replace 的价值在于:给它一个匹配规则和一个替换内容,它返回替换完成后的新字符串。

replace 的基本写法
replace 是字符串方法,基本形式是:
js
字符串.replace(匹配规则, 替换内容)本节笔记中的代码先演示了最基础的想法:
html
<body>
<script>
// 替换和修饰符
const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神'
// 1. 替换 replace 需求:把前端替换为 web
// 1.1 replace 返回值是替换完毕的字符串
// const strEnd = str.replace(/前端/, 'web') 只能替换一个
</script>
</body>这里要特别注意:replace 的返回值是“替换完毕的字符串”,它不是直接在原字符串上改。也就是说,应该用变量接住结果:
js
const strEnd = str.replace(/前端/, 'web')如果只写 str.replace(/前端/, 'web') 而不接收返回值,原字符串 str 不会变成替换后的内容,控制台也看不到结果。
为什么只替换了一个
笔记里有一句关键注释:
js
// const strEnd = str.replace(/前端/, 'web') 只能替换一个原因是:正则 /前端/ 只表示“查找前端这个模式”,在没有额外修饰符约束时,replace 只会处理第一个匹配到的“前端”。原字符串里有两个“前端”:
text
欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神第一个“前端”会被替换,第二个仍然保留。调试时如果只看到第一个位置变成 web,不要误以为 replace 坏了,而是匹配规则还没有要求“全局替换”。
修饰符 g:全部替换
修饰符用来约束正则执行的某些细节行为。g 是单词 global 的缩写,表示匹配所有满足正则表达式的结果。把它写在正则字面量第二个斜杠后面:
js
/前端/g本节最终代码是:
html
<body>
<script>
// 替换和修饰符
const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神'
// 1. 替换 replace 需求:把前端替换为 web
// 1.1 replace 返回值是替换完毕的字符串
// const strEnd = str.replace(/前端/, 'web') 只能替换一个
// 2. 修饰符 g 全部替换
const strEnd = str.replace(/前端/g, 'web')
console.log(strEnd)
</script>
</body>加上 g 后,两个“前端”都会被替换,输出结果应为:
text
欢迎大家学习web,相信大家一定能学好web,都成为web大神调试时可以按这个顺序验证:先不加 g,观察只替换第一个;再加 g,观察两个都替换。这样就能直观理解 g 的作用。
修饰符 i:忽略大小写
i 是单词 ignore 的缩写,表示正则匹配时字母不区分大小写。比如规则 /web/i 可以匹配 web、Web、WEB 等写法。它解决的是“内容相同但大小写不同”的匹配问题。
如果目标字符串里写的是 Web,而规则写成 /web/,就可能匹配不到;加上 i 后,大小写差异被忽略。注意:i 只影响字母大小写,不会改变替换结果的大小写,替换成什么仍由 replace 的第二个参数决定。
组合使用与易错点
g 和 i 可以组合使用,例如 /web/gi 或 /web/ig,表示忽略大小写并全局替换。常见易错点如下:
replace返回新字符串,原字符串不变,必须接收返回值。- 不加
g只替换第一个匹配项,不要误判为方法失效。 g、i写在正则字面量第二个斜杠后面,不要写到替换内容里。- 正则字面量是两个斜杠,不要连成注释符号。
- 第二参数是替换后的内容,写错位置会得到意外结果。
把这一节记住一句话:replace 负责替换,g 负责全部替换,i 负责忽略大小写;先写规则,再接返回值,最后看输出验证。
正则表达式的基本使用

为什么需要:表单里常要限制用户输入,例如手机号只能 11 位数字;页面反馈里要过滤敏感词;一段文字里要提取特定内容。这些都需要“字符串规则”。
怎么想:把正则理解成规则:先定义规则,再拿字符串去匹配。匹配上返回 true,匹配不上返回 false。
怎么做:用两个斜线定义字面量规则,再用 test 检测。
js
const reg = /web/;
const str = 'web前端';
console.log(reg.test(str)); // true
console.log(reg.test('java开发')); // false易错点:// 连在一起会被当成注释;正则也是对象,所以可以用 reg.test(...);test 返回布尔值,不要把它当成提取结果的方法。
边界符:开头、结尾与精确匹配
为什么需要:只写 /web/ 表示“包含 web”,但表单验证常常要求“必须以 web 开头/结尾/整体就是 web”。
怎么想:^ 管开头,$ 管结尾;两个一起用就是精确匹配。
怎么做:
js
const reg1 = /^web/; // 必须以 web 开头
const reg2 = /web$/; // 必须以 web 结尾
const reg3 = /^web$/; // 只能是 web调试时:/^web/.test('web前端') 为 true,/^web/.test('前端web') 为 false;/web$/.test('前端web') 为 true;/^web$/.test('web') 为 true,/^web$/.test('webweb') 为 false。
易错点:^ 写在中括号外表示开头;写进中括号里表示取反,后面会讲。开发中常优先用 ^...$ 做精确匹配。
量词:控制重复次数
为什么需要:手机号 11 位、用户名 6 到 16 位,都要求“重复几次”,不能只匹配单个字符。
怎么想:* 是大于等于 0 次,+ 是大于等于 1 次,? 是 0 次或 1 次;{n} 固定 n 次,{n,} 至少 n 次,{n,m} 是 n 到 m 次。
怎么做:
js
const reg1 = /^w*$/; // 0 次或多次
const reg2 = /^w+$/; // 1 次或多次
const reg3 = /^w?$/; // 0 次或 1 次
const reg4 = /^w{3}$/; // 只能 3 次
const reg5 = /^w{2,}$/; // 至少 2 次
const reg6 = /^w{2,4}$/; // 2 到 4 次易错点:大括号里逗号两侧不要加空格。转写中专门验证过:{2, 4} 这种写法会导致匹配失败;{2,4} 才是正确写法。
范围:单个字符多选一
为什么需要:只允许输入小写字母、数字或指定字符时,用普通字符一个个写太麻烦。
怎么想:中括号表示范围,但它是“匹配包含的单个字符”,即多选一;连字符 - 表示“到”;中括号内的 ^ 表示取反。
怎么做:
js
const reg1 = /^[abc]$/; // 只能是 a、b、c 中的一个
const reg2 = /^[a-z]$/; // 只能是一个小写字母
const reg3 = /^[^a-z]$/; // 不能是小写字母
const reg4 = /^[a-zA-Z0-9_-]{6,16}$/; // 用户名:字母数字下划线短横线,6到16位调试时要注意:/^[abc]$/.test('ab') 是 false,因为范围只匹配单个字符;/^[a-z]$/.test('A') 也是 false。
易错点:^ 在中括号外是开头边界,在中括号内才是取反;范围只负责一个字符,要配合量词才能限制长度。
用户名验证表单案例
为什么需要:把正则真正用到表单验证:输入不符合规则要提示,符合规则要给正确状态。
怎么想:失去焦点 blur 时验证;用正则 test 判断输入框的值;正确时让 span 显示正确类,并隐藏提示框;错误时显示错误类,并显示提示框。
怎么做:
js
const reg = /^[a-zA-Z0-9_-]{6,16}$/;
const userName = document.querySelector('.username');
const tip = document.querySelector('.tip');
userName.addEventListener('blur', function () {
const span = userName.nextElementSibling;
if (reg.test(this.value)) {
span.className = 'right';
tip.style.display = 'none';
} else {
span.className = 'wrong';
tip.style.display = 'block';
}
});调试过程中发现:如果用 classList.add,先加 wrong 再加 right 会两个类同时存在;改用 className 可以覆盖旧类。正确时还要把提示框隐藏,否则错误提示会残留。
易错点:nextElementSibling 不要加括号;验证的是 this.value,不是输入框元素本身;正确和错误状态要互斥,提示框显示/隐藏也要成对处理。
课件图示








代码示例
示例 1:replace 基本替换与 g 修饰符(全局替换)
html
<body>
<script>
// 替换和修饰符
const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神'
// 1. 替换 replace 需求:把前端替换为 web
// 1.1 replace 返回值是替换完毕的字符串
// const strEnd = str.replace(/前端/, 'web') 只能替换一个
// 2. 修饰符 g 全部替换
const strEnd = str.replace(/前端/g, 'web')
console.log(strEnd) // 欢迎大家学习web,相信大家一定能学好web,都成为web大神
console.log(str) // 原字符串不变
</script>
</body>要点解释 / 易错点
replace(正则, '替换内容')的返回值才是替换完毕的字符串,必须用变量接收或直接输出;原字符串str不会被改变(字符串是基本类型,不可变)。- 不加修饰符
g时,/前端/只会匹配并替换第一个,后面的"前端"原样保留——这是最常见的漏写错误。 g是单词 global 的缩写,表示"全局",匹配所有满足正则表达式的结果。- 正则字面量是两条斜杠
/前端/g,不要加引号写成'/前端/g',否则会被当成普通字符串,变成"把/前端/g这个文本替换掉",结果什么也不会变。
示例 2:i 修饰符(不区分大小写)
html
<body>
<script>
const str = 'Web前端很好玩,WEB开发也不难,web是基础'
// i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
console.log(str.replace(/web/, '前端')) // 只替换第一个,且区分大小写 → 匹配不到,原样输出
console.log(str.replace(/web/i, '前端')) // 忽略大小写,只替换第一个
console.log(str.replace(/web/gi, '前端')) // 忽略大小写 + 全部替换
</script>
</body>要点解释 / 易错点
i(ignore)让正则匹配时字母不区分大小写,Web、WEB、web都能被/web/i匹配到。i只解决"大小写",不解决"替换几个",所以想全部替换必须gi一起写。- 修饰符顺序不影响结果,
/web/gi和/web/ig等价,习惯上写gi。 - 易错点:只写
i不写g时,console.log看到的结果里还残留着"WEB开发"没被替换,容易误以为正则写错了,其实是修饰符没加全。
示例 3:用 g 修饰符做敏感词过滤(替换为星星)
html
<body>
<input type="text" id="msg" value="本页太傻了,上课真笨">
<button>提交反馈</button>
<p id="result"></p>
<script>
const msg = document.querySelector('#msg')
const result = document.querySelector('#result')
const btn = document.querySelector('button')
btn.addEventListener('click', function () {
// 定义敏感词的规则,g 表示匹配到的全部替换
const reg = /傻|笨/g
// replace 返回替换后的新字符串,替换成星星就看不到原话了
result.innerHTML = msg.value.replace(reg, '**')
})
</script>
</body>要点解释 / 易错点
/傻|笨/g中的|表示"或",即"傻"或"笨"任意一个都算敏感词;漏写g只会屏蔽第一个敏感词,后面的照样露出来。- 替换成
'**'是"一个敏感词替换成两个星",如果想让星星数量和敏感词字数对应,需要用到后面才学的更复杂写法,这里保持简单即可。 - 易错点:
msg.value.replace(...)的结果要赋给result.innerHTML才看得到效果,直接写msg.value.replace(reg, '**')而不接收返回值,页面上不会有任何变化。
常见错误
- 现象:
str.replace(/前端/, 'web')只改第一处。→ 原因:未加全局修饰符。→ 修法:需要全部替换时写/前端/g。 - 现象:表单输入包含规则片段也通过验证。→ 原因:规则漏写
^、$,不是精确匹配。→ 修法:补全边界,并用正例、反例各测一次。 - 现象:
/^[A-Za-z0-9_-]{6, 16}$/匹配失败或编辑器报错。→ 原因:量词逗号两侧多了空格。→ 修法:改为{6,16},逗号两侧不留空格。 - 现象:用户名规则写成多个中括号后仍只校验一个字符。→ 原因:把范围当成整段匹配,未配合量词。→ 修法:单字符集合合并到同一
[],再用{n,m}控制长度。 - 现象:先输错再输对,元素同时保留
wrong和right类。→ 原因:用classList.add追加类名,旧状态未清除。→ 修法:用className = 'right'/'wrong'覆盖,或先移除旧类。 - 现象:
/^[a-z]{3}$/.test(input)始终不符合预期。→ 原因:测试的是输入框元素对象,不是用户输入值。→ 修法:改为test(input.value)。 - 现象:验证成功后错误提示框仍显示。→ 原因:只在失败分支显示提示,成功分支未复位。→ 修法:成功时同步设置提示框隐藏。
- 现象:正则字面量写成
//web//或误当注释。→ 原因:斜杠数量或位置错误。→ 修法:字面量写/web/,需要动态拼接时用new RegExp('web')。
练习
把字符串
'前端 Web 前端 web'中所有“前端”替换为web,写出替换语句。
参考:str.replace(/前端/g, 'web')。写一个用户名精确匹配规则:6–16 位,只能由英文字母、数字、下划线、短横线组成。
参考:/^[A-Za-z0-9_-]{6,16}$/。判断以下字符串哪些能通过
/^[A-C]{2,4}$/:'AB'、'A'、'ABCD'、'AB5'、'abc'。
参考:'AB'、'ABCD'通过;其余不通过。修复代码:
if (/^[a-z]{3}$/.test(input)) { ... },要求检测输入框当前值。
参考:if (/^[a-z]{3}$/.test(input.value)) { ... }。用
replace把'a1b2c3'中所有数字替换为#,写出语句。
参考:'a1b2c3'.replace(/[0-9]/g, '#')。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 正则表达式的基本使用 | 11:15 |
| 2 | 元字符之边界符 | 09:54 |
| 3 | 元字符之量词 | 14:49 |
| 4 | 元字符之范围 | 14:55 |
| 5 | 用户名验证表单案例 | 12:43 |
小结
- 表单规则默认优先写精确匹配,并用正反例验证,不要只看“能通过”的样例。
- 需要全部替换时显式加
g;只有确实不区分大小写时才加i。 - 范围负责“单个字符可选集”,长度重复交给量词,二者组合后再测试边界长度。
- 正则中量词逗号两侧不要留空格,写完先在控制台用短样本验证。
- 验证输入框时先取
value,不要直接对元素对象调用test。 - 表单成功/失败状态都要完整处理:类名覆盖、提示框显示与隐藏要成对出现。
replace返回新字符串,必须接收返回值;原字符串不会被直接修改。- 取反符在
[]内和[]外含义不同,混用前先用小样本确认匹配结果。