标准答案
- 前端常用正则做输入格式校验、文本搜索、简单提取、替换和日志处理,例如邮箱、手机号、URL 片段、模板占位符、日志字段。
- 正则不适合解析复杂 HTML、完整 URL 语义、自然语言和任意嵌套语法。这类场景应优先使用 DOMParser、URL、专用解析器或服务端校验。
- 贪婪量词会尽可能多匹配,例如 .*;非贪婪量词在量词后加 ?,会尽可能少匹配,例如 .*?。
- 分组用括号捕获子匹配,可以通过 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 影响。
- 写出容易灾难性回溯的表达式,导致页面卡顿。