正则这种东西,学的时候都能看懂,用的时候全都想不起来。这里攒一份我自己真正高频使用的片段,配合三条避坑笔记。
常用片段
// 手机号(中国大陆,宽松版)
/^1[3-9]\d{9}$/
// 邮箱(务实版:不用 RFC 5322,够用且误杀少)
/^[\w.%+-]+@[\w.-]+\.[A-Za-z]{2,}$/
// URL(带协议)
/^https?://[\w.-]+(:\d+)?(/[\w./?%&=-]*)?$/i
// 日期 yyyy-MM-dd
/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/
// IPv4
/^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$/
// 中文字符
/[一-龥]/
// 强密码:8-20 位,至少含字母和数字
/^(?=.*[A-Za-z])(?=.*\d)[^\s]{8,20}$/
坑一:贪婪与非贪婪
const html = '<img src="a.jpg"> text <img src="b.jpg">';
// 贪婪:从头匹配到尾,一把梭(错)
/<img.*>/ // 命中整串
// 非贪婪:加 ? 就地收敛(对)
/<img.*?>/ // 分别命中两个 img
匹配成对结构(标签、引号、括号)时,几乎永远应该用非贪婪 *? / +?。
坑二:全局标志 g 的 last_Index 陷阱
const re = /ab/g;
re.test('ab'); // true
re.test('ab'); // false !
带 g 的正则对象是有状态的(lastIndex),复用同一个对象反复 test 会交替返回真假。解决办法:不复用(每次字面量新建),或用 String.prototype.match/matchAll 代替。
坑三:校验请锚定首尾
/\d{11}/.test('12345678901234567') 返回 true——因为它只负责“找得到”,不管“只有”。做格式校验时务必 ^ 和 $ 两头焊死,否则一个 30 位的字符串能轻松通过你的 11 位手机号校验。
浏览器里实时调试
Chrome DevTools 的 Console 里直接写正则即可,复杂表达式推荐 regex101.com(选 ECMAScript 方言),每一步匹配都有解释,比盯着文档猜高效得多。