标准答案

  1. 前端常用正则做输入格式校验、文本搜索、简单提取、替换和日志处理,例如邮箱、手机号、URL 片段、模板占位符、日志字段。
  2. 正则不适合解析复杂 HTML、完整 URL 语义、自然语言和任意嵌套语法。这类场景应优先使用 DOMParser、URL、专用解析器或服务端校验。
  3. 贪婪量词会尽可能多匹配,例如 .*;非贪婪量词在量词后加 ?,会尽可能少匹配,例如 .*?。
  4. 分组用括号捕获子匹配,可以通过 groups 或下标读取;(?:) 是非捕获分组。断言匹配位置但不消耗字符,例如正向前瞻 (?=)、负向前瞻 (?!), 部分环境支持后顾断言。

题目解析

正则面试题重点不是写出很长表达式,而是知道适用边界、量词行为、分组含义和断言的“只判断位置不消费字符”。

全局正则的 test 会受 lastIndex 影响,连续调用可能出现真假交替。需要重复测试时可以不用 g,或手动重置 lastIndex。

输入校验涉及安全和业务规则时,前端正则只能改善体验,服务端仍必须校验。还要避免灾难性回溯导致页面卡顿。

代码示例

下面示例展示贪婪和非贪婪、命名分组、前瞻断言和全局正则 lastIndex。

JavaScript
const html = '<span>one</span><span>two</span>'

html.match(/<span>.*<\/span>/)?.[0]
// '<span>one</span><span>two</span>',贪婪匹配尽可能多

html.match(/<span>.*?<\/span>/)?.[0]
// '<span>one</span>',非贪婪匹配尽可能少

const phone = '0571-12345678'
const match = phone.match(/^(?<area>\d{3,4})-(?<number>\d{7,8})$/)
match?.groups?.area // '0571'

'80%'.match(/\d+(?=%)/)?.[0] // '80',前瞻只判断后面有 %

const pattern = /js/g
pattern.test('js') // true
pattern.test('js') // false,lastIndex 已经移动

常见误区

  • 用正则解析任意复杂 HTML。
  • 忘记全局正则 test 会受 lastIndex 影响。
  • 写出容易灾难性回溯的表达式,导致页面卡顿。

作者信息