Skip to content

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,表示忽略大小写并全局替换。常见易错点如下:

  1. replace 返回新字符串,原字符串不变,必须接收返回值。
  2. 不加 g 只替换第一个匹配项,不要误判为方法失效。
  3. g、i 写在正则字面量第二个斜杠后面,不要写到替换内容里。
  4. 正则字面量是两个斜杠,不要连成注释符号。
  5. 第二参数是替换后的内容,写错位置会得到意外结果。

把这一节记住一句话: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,不是输入框元素本身;正确和错误状态要互斥,提示框显示/隐藏也要成对处理。

课件图示 ​

课件第26页:1.3 替换和修饰符 l 修饰符约束正则执行的某些细节行为,如是否区分大小写、是

课件第25页:1.3 替换和修饰符 l replace 替换方法,可以完成字符的替换 l 语法

课件第28页:可以帮我们快速生成正则表达式 any-rule 推荐一个vscode正则插件

课件第5页:1.1.1 什么是正则表达式 l 正则表达式(Regular Expressio

课件第7页:总结 总结 1.正则表达式是什么? Ø 是一种字符串匹配的模式(规则) 2.正则

课件第6页:1.1.2 正则基本使用 l 正则基本使用分为两步: 定义规则 使用正则 l c

课件第20页:案例 用户名验证案例 需求:用户名要求用户英文字母,数字,下划线或者短横线组成,

课件第27页:案例 利用正则隐藏手机号中间四位 分析: ①:手机号前三位显示,中间四位隐藏为*

代码示例 ​

示例 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, '**') 而不接收返回值,页面上不会有任何变化。

常见错误 ​

  1. 现象:str.replace(/前端/, 'web') 只改第一处。→ 原因:未加全局修饰符。→ 修法:需要全部替换时写 /前端/g。
  2. 现象:表单输入包含规则片段也通过验证。→ 原因:规则漏写 ^、$,不是精确匹配。→ 修法:补全边界,并用正例、反例各测一次。
  3. 现象:/^[A-Za-z0-9_-]{6, 16}$/ 匹配失败或编辑器报错。→ 原因:量词逗号两侧多了空格。→ 修法:改为 {6,16},逗号两侧不留空格。
  4. 现象:用户名规则写成多个中括号后仍只校验一个字符。→ 原因:把范围当成整段匹配,未配合量词。→ 修法:单字符集合合并到同一 [],再用 {n,m} 控制长度。
  5. 现象:先输错再输对,元素同时保留 wrong 和 right 类。→ 原因:用 classList.add 追加类名,旧状态未清除。→ 修法:用 className = 'right'/'wrong' 覆盖,或先移除旧类。
  6. 现象:/^[a-z]{3}$/.test(input) 始终不符合预期。→ 原因:测试的是输入框元素对象,不是用户输入值。→ 修法:改为 test(input.value)。
  7. 现象:验证成功后错误提示框仍显示。→ 原因:只在失败分支显示提示,成功分支未复位。→ 修法:成功时同步设置提示框隐藏。
  8. 现象:正则字面量写成 //web// 或误当注释。→ 原因:斜杠数量或位置错误。→ 修法:字面量写 /web/,需要动态拼接时用 new RegExp('web')。

练习 ​

  1. 把字符串 '前端 Web 前端 web' 中所有“前端”替换为 web,写出替换语句。
    参考:str.replace(/前端/g, 'web')。

  2. 写一个用户名精确匹配规则:6–16 位,只能由英文字母、数字、下划线、短横线组成。
    参考:/^[A-Za-z0-9_-]{6,16}$/。

  3. 判断以下字符串哪些能通过 /^[A-C]{2,4}$/:'AB'、'A'、'ABCD'、'AB5'、'abc'。
    参考:'AB'、'ABCD' 通过;其余不通过。

  4. 修复代码:if (/^[a-z]{3}$/.test(input)) { ... },要求检测输入框当前值。
    参考:if (/^[a-z]{3}$/.test(input.value)) { ... }。

  5. 用 replace 把 'a1b2c3' 中所有数字替换为 #,写出语句。
    参考:'a1b2c3'.replace(/[0-9]/g, '#')。

原视频对照 ​

#视频时长
1正则表达式的基本使用11:15
2元字符之边界符09:54
3元字符之量词14:49
4元字符之范围14:55
5用户名验证表单案例12:43

小结 ​

  1. 表单规则默认优先写精确匹配,并用正反例验证,不要只看“能通过”的样例。
  2. 需要全部替换时显式加 g;只有确实不区分大小写时才加 i。
  3. 范围负责“单个字符可选集”,长度重复交给量词,二者组合后再测试边界长度。
  4. 正则中量词逗号两侧不要留空格,写完先在控制台用短样本验证。
  5. 验证输入框时先取 value,不要直接对元素对象调用 test。
  6. 表单成功/失败状态都要完整处理:类名覆盖、提示框显示与隐藏要成对出现。
  7. replace 返回新字符串,必须接收返回值;原字符串不会被直接修改。
  8. 取反符在 [] 内和 [] 外含义不同,混用前先用小样本确认匹配结果。