学习前提

理解捕获组、分支和量词;本课区分位置断言与字符消费。

本课完成后你能做什么

区分行边界、点号范围与只检查不消耗的断言。

先理解机制

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,前两项匹配,第三项不匹配。空格放在断言内,所以不会包含在匹配结果里。

进一步阅读