学习前提
理解字符串、布尔判断与函数;正则基础也可从独立正则课程开始。
本课完成后你能做什么
为明确规则设计小而可解释的模式,并用反例区分匹配与完整验证。
先理解机制
正则适合识别文本模式,不适合承担全部业务规则。先用自然语言定义允许字符、长度与边界,再写表达式。用户名是否已经被使用、链接是否真的存在都不能仅靠正则判断。简单关键词查找常用includes即可,不必为了工具而增加复杂度。
字符类规定一个位置可取哪些字符,量词规定重复次数,锚点限定位置。test找到某个匹配即可成功,不自动要求整串都是目标。校验时还要理解换行与多行模式,不能机械地给任何模式加两个符号就认为所有边界解决。
g或y标志的test会推进lastIndex,重复测试同一字符串可能出现交替结果。用于独立输入校验时通常不需要g。捕获组用于提取结构,非捕获组用于组织规则;给复杂规则起函数名并附反例,比写一条难读的巨大表达式更可靠。
不要把未处理的用户输入直接拼进正则,特殊字符会改变模式含义。对不受控的大输入和复杂嵌套重复保持谨慎;先限制长度、保持规则简单。格式验证通过后仍要由服务端重复验证。
可运行示例
运行方式:在独立练习网页的开发者工具Console中运行JavaScript;不要在含有重要表单的页面练习。修改输入后重新运行完整示例。
function validHandle(raw) {
// Policy: 3–16 ASCII letters, digits or underscores; first is a letter.
return raw.length >= 3 && raw.length <= 16
&& /^[A-Za-z]/.test(raw)
&& !/[^A-Za-z0-9_]/.test(raw);
}
for (const value of ['Ada_1', 'ab', '1Ada', 'Ada!', 'Ada\n', '张三']) {
console.log(JSON.stringify(value), validHandle(value));
}
const stateful = /a/g;
console.log(stateful.test('a'), stateful.test('a'));
推演与验证
只有Ada_1通过,其余依次因为太短、开头数字、符号、换行、超出ASCII规则失败。最后两次test结果true和false,观察lastIndex解释原因。该规则刻意限制ASCII,是示例产品约定,不是所有网站用户名的通用要求。
常见错误与边界
把中文姓名拿来套英文用户名规则是需求错误,不是用户输入错误。邮箱完整语法复杂,通常优先type=email配合服务端确认,不要宣称简短正则能验证邮箱真实存在。
动手练习
提取形如lesson-42的编号,只接受正整数,不接受lesson-0、lesson-42x或前后空格。返回数字或null。
参考解法与理由
用捕获组提取后检查整段匹配长度,避免最终换行的锚点细节造成意外接受。随后检查安全整数范围,字符串看起来是数字仍可能超过精度。
function lessonId(text) {
const match = /^lesson-([1-9][0-9]*)/.exec(text);
if (!match || match[0].length !== text.length) return null;
const id = Number(match[1]);
return Number.isSafeInteger(id) ? id : null;
}