
文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载导读在编写样式解析、主题提取、网页数据抓取等工具时最常见的需求之一就是从文本中精确识别 HTML/CSS 颜色代码。本篇文章基于 en.javascript.info 教程正则表达式章节中 Regexp for HTML colors 这一实战任务系统讲解如何用量词{6}、字符类[0-9a-f]与边界断言\b组合出一个既正确又健壮的正则表达式。读完本文你将掌握量词的精确定数与范围语法、g/i标志的作用以及如何避免长串误匹配这一经典陷阱并能在真实项目中直接落地使用。任务还原目标与约束原任务task.md要求创建一个正则表达式用于在文本中搜索以#开头、后跟6 个十六进制字符的 HTML 颜色#ABCDEF示例测试字符串与期望输出let regexp /...your regexp.../ let str color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2 #12345678; alert( str.match(regexp) ) // #121212,#AA00ef任务给出了三条明确约束只处理 6 位十六进制格式#1233 位缩写、rgb(1,2,3)等其他 CSS 颜色格式不在本任务范围内十六进制字符大小写不敏感#AA00ef中的大写A与小写ef都应被匹配排除伪装成颜色的片段f#fddee前面有字母f且只有 5 位十六进制、#fd2位数不足、#12345678位数超过 6都不算合法颜色。前置知识量词{n}与十六进制字符类量词{n}精确指定重复次数本任务的第一个知识点来自 09-regexp-quantifiers 章节。正则表达式中的量词quantifier用于指定某个字符、字符类或集合的重复次数最简单的形式就是花括号里的数字pattern:{5}—— 恰好出现 5 次\d{5}等价于\d\d\d\d\dpattern:{3,5}—— 出现 3 到 5 次pattern:{3,}—— 出现 3 次及以上上限省略。任务要求的恰好 6 个十六进制字符正是量词{6}的典型应用场景。除了精确计数{n}量词章节还介绍了三个常用缩写缩写含义等价写法一次或多次{1,}?零次或一次可选{0,1}*零次或多次{0,}十六进制字符类[0-9a-fA-F]十六进制数字包含0-9、a-f、A-F用字符类character class可以简洁地表达为[0-9a-fA-F]这正是 02-regexp-character-classes 章节 所讲的方括号集合语法。不过如果配合正则表达式的iignore case忽略大小写标志A-F的部分可以省略[0-9a-f]加上i后a-f会同时匹配大小写。这也是原文档 solution.md 采用的写法。第一版解决方案/#[a-f0-9]{6}/gi把两个知识点组合起来#字面量 字符类[a-f0-9]重复恰好 6 次即得到第一版正则let regexp /#[a-f0-9]{6}/gi; let str color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2; alert( str.match(regexp) ); // #121212,#AA00ef两个标志的作用gglobal让str.match()返回字符串中所有匹配项组成的数组而非仅第一个匹配。这一点在 17-regexp-methods 章节 中有详细说明带g时match返回全部匹配字符串数组不带g时返回包含捕获组和index/input信息的首匹配数组iignore case使[a-f0-9]同时覆盖大写A-F从而命中#AA00ef。至此#121212与#AA00ef被正确识别而f#fddee缺少一位与#fd2位数严重不足被排除。经典陷阱长串误匹配第一版正则还有一个隐藏问题——它会在更长的连续十六进制序列中截取前 6 位当作颜色alert( #12345678.match( /#[a-f0-9]{6}/gi ) ) // #123456#12345678本身并不是合法的 6 位颜色它有 8 位但量词{6}只要求恰好 6 个十六进制字符它会在#12345678中匹配到#123456这一子串导致误报。问题根源在于量词只约束匹配长度不约束匹配边界。正则引擎会在字符串任意位置寻找符合条件的子串只要找到连续 6 个十六进制字符就视为命中即便后面还紧跟着更多十六进制字符。边界修正引入\b单词边界解决方案是在正则末尾追加单词边界断言\b// 合法的 6 位颜色 → 匹配 alert( #123456.match( /#[a-f0-9]{6}\b/gi ) ); // #123456 // 8 位长串 → 不匹配 alert( #12345678.match( /#[a-f0-9]{6}\b/gi ) ); // null\b的判定原理\b是一个零宽断言zero-width assertion它不消耗任何字符只在当前位置检查是否为单词边界。根据 06-regexp-boundary 章节 的定义满足以下三种情况之一即为单词边界字符串开头且首字符是单词字符\w字符串内部一侧是单词字符\w、另一侧不是字符串末尾且最后一个字符是单词字符\w。其中\w等价于[a-zA-Z0-9_]。在#12345678中第 6 位十六进制字符6与第 7 位7之间两侧都是单词字符因此该位置不是单词边界\b断言失败整个匹配被拒绝。而在#123456末尾6之后是分号、空格等非单词字符满足边界条件匹配成功。最终答案即为let regexp /#[a-f0-9]{6}\b/gi;深入验证在完整测试字符串上验证将最终正则应用回任务的完整测试用例逐一验证每个候选片段let regexp /#[a-f0-9]{6}\b/gi; let str color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2 #12345678; alert( str.match(regexp) ); // #121212, #AA00ef文本片段判定原因#121212✅ 匹配# 6 位十六进制后面是;非单词字符#AA00ef✅ 匹配大小写混合的 6 位十六进制i标志生效f#fddee❌ 不匹配前面有单词字符f且#后只有 5 位十六进制#fd2❌ 不匹配位数不足 6#12345678❌ 不匹配{6}后\b断言失败长串被排除补充验证一\b对首部边界的保护\b同时还会在匹配起始位置前做边界检查。例如f#fddee这类颜色代码前紧贴单词字符的情况即便位数凑够#前侧的f与#非单词字符之间虽然存在边界但注意此时正则引擎是从f之后开始尝试匹配#的——#本身不是单词字符所以真正起拦截作用的是位数不足。若换成f#1234566 位由于#前紧贴f匹配起始位置位于f与#之间此处两侧分别是单词字符f和非单词字符#恰好满足边界条件因此仍会命中#123456。若要进一步收紧为颜色代码必须是独立 token可以在#前也加上\b或改用更严格的上下文但原任务并未要求这一层过滤。补充验证二g标志与match的返回行为根据 17-regexp-methods 章节 的说明带g标志时str.match(regexp)返回所有匹配的字符串数组无匹配时返回null而非空数组。例如alert( no colors here.match(/#[a-f0-9]{6}\b/gi) ); // null如果希望始终得到数组可以写成str.match(regexp) || []。这一行为差异在实际项目中如遍历结果前判断空值需要特别留意。实战扩展从找出颜色到解析与替换掌握了核心正则之后可以结合仓库其他章节的方法把它应用到真实场景中。场景一逐个提取并校验颜色当需要拿到每个颜色及其在字符串中的位置时可用regexp.exec配合lastIndex循环遍历17-regexp-methods 章节或直接用matchAll获得带索引的迭代器let regexp /#[a-f0-9]{6}\b/gi; let str color:#121212; background-color:#AA00ef; for (let match of str.matchAll(regexp)) { alert( match[0] at position match.index ); } // #121212 at position 6 // #AA00ef at position 30场景二颜色归一化统一转为大写利用replace的回调函数参数可以把提取出的所有颜色统一转为大写或小写便于后续比较let str color:#121212; background-color:#AA00ef; let normalized str.replace(/#[a-f0-9]{6}\b/gi, m m.toUpperCase()); alert(normalized); // color:#121212; background-color:#AA00EF场景三与其他颜色格式的取舍本任务刻意不处理#1233 位缩写和rgb(1,2,3)等格式。若你的需求必须兼容 3 位缩写可将其量词改为可选例如/#[a-f0-9]{3}(?:[a-f0-9]{3})?\b/gi——这正是量词章节中正则越精确就越复杂这一规律的体现09-regexp-quantifiers每多一种格式需求就需要多一层分支与分组同时也要重新评估\b边界在不同格式下的表现。建议按需取舍而不是一开始就堆砌一个万能正则。小结量词{n}用于精确指定字符重复次数/#[a-f0-9]{6}/gi可匹配#后跟恰好 6 个十六进制字符i标志让[a-f0-9]同时匹配大小写g标志让match返回全部匹配必须用\b收尾否则#12345678这类长串会被误截为#123456\b是零宽断言只在两侧一方为\w、另一方非\w的位置成立最终方案/#[a-f0-9]{6}\b/gi并通过str.match()、matchAll、replace等方法直接落地到提取、定位、归一化等真实业务中。这一任务的完整过程——从需求拆解、量词选用、标志配置到边界陷阱修复——是理解正则表达式精确匹配思想的绝佳范例相关源码与讲解均可在本仓库 9-regular-expressions 目录下找到对应章节继续深入学习。赞分享文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载相关推荐在 JavaScript 中把 3 位十六进制颜色码扩展为 6 位30 seconds of code 的 extendHex 实战在 JavaScript 中把 3 位十六进制颜色码扩展为 6 位30 seconds of code 的 extendHex 实战 3 位十六进制颜色码如教程文档从安装到部署uiw组件库完整使用教程附TypeScript示例从安装到部署uiw组件库完整使用教程附TypeScript示例 uiw是一个基于React 16的高质量UI组件库提供了丰富的组件和工具帮助开发者快N_m3u8DL-RE 完整指南一键下载加密 DASH 流N_m3u8DL RE 完整指南一键下载加密 DASH 流 你手里只有一个 .mpd 链接课程却用了 CENC 加密页面能看不能存换三个工具都没跑通。NCLI音视频创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考