学习前提
需要了解JavaScript字符串、数组与函数。使用现代浏览器控制台,或保存lesson.js后用Node.js运行;各章独立执行。
本课完成后你能做什么
区分普通字符串与正则模式,建立可验证的输入规则。
先理解机制
正则表达式描述字符序列的模式。test回答是否找到匹配,exec返回首次匹配及位置。默认是搜索子串,不是验证整个输入;“能找到数字”与“全部由数字组成”是两个需求。
字面量/模式/适合写在源码中的固定规则;new RegExp接收字符串,所以字符串转义与正则转义是两层。要在构造器中表达反斜杠d,源字符串必须写成"\\d"。
本例编号由HS-加四位ASCII数字组成。^和$在不使用m时约束输入起止位置;点号默认表示一个非换行字符,匹配真实点号需要转义。规则应先用自然语言写清楚,再转换成模式。
可运行示例
const search = /\d+/;
const whole = /^HS-\d{4}$/;
const constructed = new RegExp("^HS-\\d{4}$");
console.log(JSON.stringify(["HS-0042", "xHS-0042", "HS-42", "HS-0042\n"].map(s => whole.test(s))));
console.log(search.exec("part 42 ready")[0]);
console.log(constructed.test("HS-0042"));
console.log(/file\.js/.test("fileXjs"));
推演与验证
四个输入只有第一个通过;搜索方法从句子中提取42。构造器规则与字面量一致,转义后的点号不会接受X。
常见错误与边界
本课程使用JavaScript正则方言;其他语言的边界、标志和替换语法可能不同。若只是检查固定文本是否出现,includes通常更清楚。
动手练习
将规则改为AB-后接三位数字,测试AB-000、AB-1234及空字符串。
参考解法与理由
使用/^AB-\d{3}$/,结果为true、false、false。不要加入g,因为这里不是连续搜索任务。
深入实验:搜索匹配与完整校验的区别
规则要求整段输入是HS-加四位ASCII数字,不允许前后空白。不能把“找到了看起来正确的片段”当作整个字段合格。JavaScript开启m后,^和$会匹配行边界;下面比较搜索、按行匹配与不带m的整串约束。
在现代浏览器Console中独立运行这个实验;它不替换上方主示例。
const loose = /HS-[0-9]{4}/;
const familiar = /^HS-[0-9]{4}$/m;
const exact = /^HS-[0-9]{4}(?![\s\S])/;
for (const input of ['HS-1234', 'xHS-1234', 'HS-1234\n', 'HS-1234']) {
console.log(JSON.stringify(input), loose.test(input), familiar.test(input), exact.test(input));
}
console.assert(exact.test('HS-1234'));
console.assert(!exact.test('HS-1234\n'));
预期观察
四行真假组合依次为true/true/true、true/false/false、true/true/false、false/false/false。末尾换行是这个实验刻意保留的反例。
原因、取舍与适用边界
exact不使用m;开头^约束输入起点,(?![\s\S])要求后面不再有任何UTF-16字符。另一个清楚的策略是取得匹配对象,再检查index为0且匹配长度等于输入长度。不要随手trim后再验证,除非产品明确允许忽略首尾空白;否则你改变的是验收规则。ASCII编号也不应被无意扩展为所有语言的数字字符。
进阶练习
把规则改成恰好6位数字,列出最少五种边界输入。
解法与推理
测试空串、5位、6位、7位、尾换行、全角数字。可用/^[0-9]{6}(?![\s\S])/,不要加g,因为反复test时它会引入lastIndex状态。不同正则引擎的锚点和API语义可能不同,移植时重新运行同一组样例。