学习前提
理解捕获组、分支和量词;本课区分位置断言与字符消费。
本课完成后你能做什么
区分行边界、点号范围与只检查不消耗的断言。
先理解机制
m只改变^和$的行边界语义,不让点号跨行;s才让点号包含行终止符。g请求多个匹配,i忽略大小写,各标志解决不同问题。
(?=...)检查后面能匹配什么,但不把该部分放入整体匹配;(?!...)要求后面不能匹配。断言会影响成功与失败,却不消耗字符。
本例先提取INFO行,再提取紧跟ms的数字。仅需排除少数完整保留词时,先用清晰格式规则,再用集合判断通常比堆叠断言易维护。
可运行示例
const lines = "INFO ready\nERROR stopped\nINFO done";
console.log(JSON.stringify(lines.match(/^INFO .+$/gm)));
console.log(JSON.stringify("12ms 7s 40ms".match(/\d+(?=ms)/g)));
console.log(/a.b/.test("a\nb"), /a.b/s.test("a\nb"));
const id = /^(?!admin$)[a-z]{3,12}$/;
console.log(JSON.stringify(["admin", "administrator", "reader"].map(s => id.test(s))));
推演与验证
INFO提取两行;数字结果只有12与40。普通点号不跨行,s版本可以。admin被排除,administrator因长度13也失败,reader通过。
常见错误与边界
对整段输入做验证时不要随意加m,否则某一行通过可能就让test返回true。断言不是业务日期、地址或权限的完整验证器。
动手练习
要求数字后可以有一个空格再跟ms,但结果仍只提取数字。
参考解法与理由
把断言改成(?= ?ms),测试12ms、12 ms、12 ms,前两项匹配,第三项不匹配。空格放在断言内,所以不会包含在匹配结果里。