正则表达式入门:从表单校验到日志提取
正则表达式入门:从表单校验到日志提取
正则表达式大概是"投入产出比"最高的语法之一:学会 20% 的语法能解决 80% 的字符串匹配问题。整理一下我自己的学习路径。
最小语法集
- 字符类:
\d数字、\w单词字符、\s空白、[abc]集合、[^abc]排除、.任意 - 量词:
*0+、+1+、?0或1、{n,m}范围 - 位置:
^开头、$结尾、\b单词边界 - 分组:
(abc)捕获、(?:abc)不捕获、|或
例子一:手机号校验
const phoneRe = /^1[3-9]\d{9}$/
phoneRe.test('13812345678') // true
拆开看:^ 开头必须是 1,第二位 3-9,后面再跟 9 个数字,$ 到结尾。校验类正则一定要加 ^ 和 $,否则 'abc13812345678xyz' 也能通过。
例子二:从日志里提取数据(分组捕获)
const log = '[2018-02-10 14:30:00] ERROR user_id=42 msg="login failed"'
const re = /\[(.*?)\] (\w+) user_id=(\d+)/
const match = log.match(re)
match[1] // '2018-02-10 14:30:00'
match[2] // 'ERROR'
match[3] // '42'
每个括号捕获一组,按序号从 match[1] 开始取。.*? 里的 ? 是非贪婪——匹配到第一个 ] 就停,而不是一直吃到最后一个。
例子三:replace 配合捕获组
// 驼峰转连字符
'backgroundColor'.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase())
// 'background-color'
// 用 $1 引用捕获组:日期格式转换
'2018-02-10'.replace(/(\d{4})-(\d{2})-(\d{2})/, '$2/$3/$1')
// '02/10/2018'
replace 传函数时第一个参数是完整匹配,后面依次是捕获组,非常灵活。
例子四:命名捕获组(ES2018)
序号多了容易数错,可以给分组起名字:
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const { groups } = '2018-02-10'.match(re)
groups.year // '2018'
常见坑
- 转义:匹配
.本身要写\.;在 new RegExp 字符串里反斜杠要双重转义'\\d',能用字面量/\d/就别用构造函数 - 贪婪匹配:
.*默认吃到撑,多数时候想要的是.*? - lastIndex 陷阱:带
g标志的正则反复调 test() 会从上次的 lastIndex 继续,结果忽 true 忽 false。循环校验要么去掉 g,要么每次重置 lastIndex - 别拿正则解析 HTML:嵌套结构不是正则的能力范围,老笑话了但每年都有人试
我的建议
- 常用校验(邮箱、手机号、URL)直接用成熟库或社区验证过的表达式,别自己造
- 写复杂正则时拆行加注释(
x标志),或者干脆拆成几个小正则 - 在线工具(regex101 之类)能逐字符解释匹配过程,学习期神器
正则不是背出来的,是查出来的。记住核心语法,剩下的交给速查表。
看到这里了?如果这篇文章帮到过你
请我喝瓶可乐就好 🥤

评论0 条
还没有评论,来抢沙发~