ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

javascript.info 正则实战:用捕获组与锚点校验 MAC 地址格式

javascript.info 正则实战:用捕获组与锚点校验 MAC 地址格式 文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载导读MAC 地址Media Access Control 地址是网络接口的物理标识其标准格式为 6 组两位十六进制数字、以冒号分隔例如01:32:54:67:89:AB。本篇文章基于 Modern JavaScript Tutorial 仓库中 Check MAC-address 任务 及其 官方解法带你从零构造一个既能精准匹配又能完整校验的正则表达式并深入剖析其中三个核心语法点字符集与精确量词{2}、捕获组配合量词{5}作用于整体、以及锚点^...$实现整串校验。读完本文你不仅能独立写出 MAC 地址校验正则还能掌握把一组模式当作整体重复与严格整串匹配这两类高频正则设计思路。任务背景MAC 地址的格式定义在动手写正则之前先明确校验目标。根据任务描述一个合法的 MAC 地址由6 个两位十六进制数字组成数字之间用冒号分隔NN:NN:NN:NN:NN:NN其中每个NN都是两位十六进制数。十六进制数字的范围是0-9和a-f以及对应的大写A-F例如任务给出的合法样例01:32:54:67:89:AB→ 合法同时任务给出了三类必须判为false的非法输入0132546789AB→ 缺少冒号分隔符01:32:54:67:89→ 只有 5 组数字数量不足01:32:54:67:89:ZZ→ 末组ZZ不是十六进制数字。这意味着我们的正则不仅要能找到类似结构还要求输入的整串内容严格符合格式——这正是校验类正则与搜索类正则的关键区别。完整任务描述见 task.md。第一步描述两位十六进制数字——字符集与精确量词正则里最基础的构建块是字符类character class与量词quantifier这两个概念分别由仓库中的 字符类章节 和 量词章节 系统讲解。用字符集限定十六进制字符预定义的\d只匹配0-9十进制数字无法覆盖a-f因此我们需要自定义字符集character set[0-9a-f]这个集合表示匹配0-9或a-f中的任意一个字符。写法上也可以写成[a-f0-9]或[0-9A-Fa-f]顺序不影响匹配结果因为字符集本质上是集合内任一字符。用精确量词{2}固定位数量词{n}表示恰好重复 n 次。两位十六进制数字即[0-9a-f]{2}等价于手写[0-9a-f][0-9a-f]。相比手写量词让模式更紧凑、更易读这也是量词章节中强调的{5}等价于\d\d\d\d\d的推广思路。大小写问题十六进制通常不区分大小写AB与ab同样合法。有两种处理方式在字符集中显式列出[0-9A-Fa-f]保持小写集合[0-9a-f]并给整个正则加上i标志ignore case。官方解法采用第二种更简洁/[0-9a-f]{2}/i第二步重复 5 次 :NN——捕获组让量词作用于整体现在有了一个两位十六进制数还需要冒号 两位十六进制数这个复合单元再重复 5 次才能凑齐 6 组。如果直接写:[0-9a-f]{2}{5}量词{5}只会作用在紧邻它的字符上——这里是[0-9a-f]这个字符类语义完全错误。这正是捕获组capturing group的经典用途。在正则中用小括号(...)包裹的模式会被视为一个整体其后的量词作用于整个括号组。仓库的 Capturing groups 章节 给出了同款思路的经典例子(go)表示go、gogo、gogogo等整体重复而go只表示g后面跟一个或多个o。应用到 MAC 地址上(:[0-9a-f]{2}){5}含义为冒号 两位十六进制数这个整体恰好出现 5 次。与前面独立的[0-9a-f]{2}拼起来完整结构就是第 1 组[0-9a-f]{2}之后 5 次(:[0-9a-f]{2})合计 6 组即[0-9a-f]{2}(:[0-9a-f]{2}){5}注意一个设计上的权衡第一个两位十六进制数不放进括号组而是单独写因为第一组前面没有冒号与后续五组结构不同。若将整体写成([0-9a-f]{2}:){5}[0-9a-f]{2}也完全等价且同样常见——两种写法都成立读者可自行选择习惯的形态。另外值得说明的是这里的小括号只是为了组合 应用量词我们并不需要从匹配结果中引用括号内容。若想保持结果数组干净可以换成非捕获组(?:...)同样在 Capturing groups 章节 的 Non-capturing groups with ?: 小节讲解[0-9a-f]{2}(?::[0-9a-f]{2}){5}。不过对于纯test()校验场景捕获组与否对结果没有影响。第三步严格整串校验——锚点 ^ 与 $到这一步[0-9a-f]{2}(:[0-9a-f]{2}){5}已经能匹配合法的 MAC 地址结构但仅用它做test()校验会有严重漏洞正则默认是部分匹配只要字符串中某一段符合模式就返回true。例如X01:32:54:67:89:AB会返回true模式从第 2 个字符开始命中01:32:54:67:89也会返回true前 5 组命中正则并不关心后面还有没有内容。解决方式是用锚点把匹配钉死在整个字符串的两端^匹配文本开头$匹配文本结尾两者合用的^...$表示整个字符串必须完整匹配模式任何多余或缺失的字符都会导致失败。这正是仓库中 锚点章节 的 Testing for a full match 小节所强调的用法——文中用^\d\d:\d\d$校验12:34时间格式的例子与本任务如出一辙锚点本身是零宽度测试不消耗字符只强制引擎检查位置条件。官方解法因此给出^[0-9a-f]{2}(:[0-9a-f]{2}){5}$加上i标志后得到最终答案let regexp /^[0-9a-f]{2}(:[0-9a-f]{2}){5}$/i;最终解法与完整验证将官方解法见 solution.md原样运行所有用例均符合预期let regexp /^[0-9a-f]{2}(:[0-9a-f]{2}){5}$/i; alert( regexp.test(01:32:54:67:89:AB) ); // true alert( regexp.test(0132546789AB) ); // false无冒号 alert( regexp.test(01:32:54:67:89) ); // false只有 5 组需 6 组 alert( regexp.test(01:32:54:67:89:ZZ) ); // false末组 ZZ 非法逐条回看这组测试正好验证了三个语法点的必要性测试输入结果失败/通过的机制01:32:54:67:89:ABtrue结构完整i标志接受大写AB0132546789ABfalse缺少冒号(:[0-9a-f]{2}){5}无法匹配01:32:54:67:89false只有 5 组{5}要求 6 组齐备01:32:54:67:89:ZZfalseZZ不在[0-9a-f]集合内以上代码可在浏览器控制台或 Node.js 中直接运行验证仓库示例均以run标记支持在线执行。深度剖析一去掉锚点会发生什么理解锚点价值的最好方式是反证。假如我们写出不带锚点的版本let regexp /[0-9a-f]{2}(:[0-9a-f]{2}){5}/i;那么regexp.test(x01:32:54:67:89:ABx)会返回true因为正则能在字符串内部找到符合条件的片段regexp.test(01:32:54:67:89)也会返回true因为前 5 组命中后test()不要求模式耗尽整个字符串。这与校验的语义完全相悖。由此可提炼一条通用设计原则同样在 锚点章节 中被明确总结当你需要校验整个输入是否符合格式而非在文本中搜索格式时务必用^与$包裹模式。锚点^...$是整串匹配语义的标准表达适用于输入校验、表单验证、配置解析等所有全有或全无的场景。深度剖析二从校验到提取——量词作用对象的辨析同一个任务还可以横向对比仓库中同章节的姊妹任务进一步强化量词作用于谁的判断力在 Find color in the format #abc or #abcdef 中颜色值允许3 位或 6 位十六进制解法用括号组配合范围量词{1,2}/#([a-f0-9]{3}){1,2}/gi。它解决的是可选数量问题并配合\b词边界避免误匹配#abcd中的#abc而本任务 MAC 地址要求精确 5 次重复量词{5}用在括号组之后解决的是固定数量问题。两者对比可以看出括号组的通用价值无论是{1,2}还是{5}只要需要把一组复合模式当作整体重复若干次就必须借助(...)组合。这也正是 Capturing groups 章节 开篇定义的第二条效果If we put a quantifier after the parentheses, it applies to the parentheses as a whole括号后的量词作用于括号整体。实战扩展从校验到提取与替换test()只能回答是否合法。若实际需求变为从日志中提取所有 MAC 地址或批量校验一个数组可以基于同一模式做如下演进1. 提取文本中的所有 MAC 地址——去掉锚点并加g标志用matchAll逐条取回含index位置信息可参见 Capturing groups 章节 的 matchAll 小节let regexp /[0-9a-f]{2}(:[0-9a-f]{2}){5}/gi; let log client 01:32:54:67:89:AB connected; router 0A:1B:2C:3D:4E:5F up; for (let m of log.matchAll(regexp)) { console.log(m[0]); } // 输出01:32:54:67:89:AB 0A:1B:2C:3D:4E:5F注意提取场景通常建议配合词边界或前后分隔符如\b、引号避免从更长的字符串中截出片段——这与颜色任务的\b收尾思路一致。2. 批量校验数组——将正则复用于Array.prototype.every即可一次性判定整批输入let regexp /^[0-9a-f]{2}(:[0-9a-f]{2}){5}$/i; let inputs [01:32:54:67:89:AB, 00:00:00:00:00:00, bad:input]; alert(inputs.every(mac regexp.test(mac))); // false3. 归一化格式——若需要将小写统一为大写可用replace 正则配合字符串方法let regexp /^[0-9a-f]{2}(:[0-9a-f]{2}){5}$/i; let mac 01:32:54:67:89:ab; if (regexp.test(mac)) { alert(mac.toUpperCase()); // 01:32:54:67:89:AB }4. 分组捕获便于逐段处理——将模式改写为捕获组版本^([0-9a-f]{2})(:([0-9a-f]{2})){5}$后可以用match的结果数组按编号访问各段编号规则result[0]为完整匹配result[1]起依次对应各组详见 Capturing groups 章节 的 Parentheses contents in the match 小节若嫌编号难记还可以用命名组(?part...)通过result.groups.part访问。小结围绕 MAC 地址校验这一个任务我们系统性复习并串起了正则表达式中最核心的四块知识字符集 精确量词[0-9a-f]{2}精确表达两位十六进制数字捕获组 量词(:[0-9a-f]{2}){5}让重复作用于复合单元整体这是本任务的主题所在——它正出自 Capturing groups 章节锚点整串匹配^...$把部分匹配升级为严格校验与 锚点章节 的^\d\d:\d\d$时间校验一脉相承标志i以最小代价处理十六进制的大小写兼容。最终答案一行即可落地let regexp /^[0-9a-f]{2}(:[0-9a-f]{2}){5}$/i;这套先拆结构、再组单元、最后钉锚点的方法论同样适用于 IP 地址、UUID、日期时间等一切定长分隔结构的格式校验值得在日常开发中反复套用。赞分享文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载相关推荐Node.js连接SQL Server终极指南node-mssql完全解析Node.js连接SQL Server终极指南node mssql完全解析 在Node.js生态系统中连接Microsoft SQL Server数据库一直后端Sphinx linkcheck 构建器实战锚点忽略规则与本地链接校验机制解析Sphinx linkcheck 构建器实战锚点忽略规则与本地链接校验机制解析 本篇指南以 Sphinx 仓库中 linkcheck 构建器的真实测试样例 t文档开发工具10个Habitica iOS隐藏技巧提升习惯养成效率的秘诀10个Habitica iOS隐藏技巧提升习惯养成效率的秘诀 想要将你的习惯养成游戏化体验提升到全新水平吗Habitica iOS应用作为一款创新的习惯养成移动开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表