用正则匹配十六进制颜色 abc 与 abcdef:捕获组、量词与单词边界的实战练习

发布时间:2026/10/8 7:19:31
用正则匹配十六进制颜色 abc 与 abcdef:捕获组、量词与单词边界的实战练习 文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载#3f3、#AA00ef这类十六进制颜色值是 CSS 中最常见的书写格式#后跟 3 位或 6 位十六进制数字。本文以 javascript.info 仓库中的练习任务 02-find-webcolor-3-or-6 为主线从基础解法逐步推导出/#([a-f0-9]{3}){1,2}\b/gi这个最终答案并借此讲透三个关键机制字符类与量词的组合、捕获组让量词作用于整体、\b单词边界如何堵住误匹配。读完后你将能独立写出3 位或 6 位、不多不少这类精确数量约束的正则并理解捕获组在匹配结果与替换操作中的实际价值。任务要求拆解原练习文档给出了非常精确的匹配规则匹配形如#abc或#abcdef的颜色值即#后跟3 或 6 个十六进制数字十六进制数字包含0-9和a-f大小写不敏感所以#AA00ef这种大写混合写法也必须命中必须是恰好 3 位或 6 位#abcd这类 4 位写法不允许匹配。配套的示例数据与期望输出为let regexp /your regexp/g; let str color: #3f3; background-color: #AA00ef; and: #abcd; alert( str.match(regexp) ); // #3f3 #AA00ef注意最后一项#abcd不参与输出这是整个任务真正的难点——正则引擎默认会贪心地在#abcd里找到前 3 位#abc我们必须用额外的机制把它排除掉。第一步用字符类与精确量词匹配 3 位十六进制先解决最简单的问题匹配 3 位十六进制数字。字符类[a-f0-9]表示a到f或0到9中的任意一个字符参见仓库的 字符类章节该章节还介绍了\d、\s、\w等常用类其中\w仅涵盖拉丁字母、数字和下划线。恰好 3 个用精确量词{3}表达它在 量词章节 中有详细说明{n}表示恰好 n 次\d{5}等价于\d\d\d\d\d{3,5}表示 3 到 5 次{3,}表示至少 3 次。组合起来再配合i标志忽略大小写使[a-f0-9]同样匹配大写A-F得到第一个版本let regexp /#[a-f0-9]{3}/i; alert( #3f3.match(regexp) ); // #3f3 alert( #AA00ef.match(regexp) ); // #AA0 - 只取了前 3 位还不是想要的这里立刻暴露出两个问题#AA00ef只匹配到了#AA0而且匹配到的结果没有包含大小写完整的原文之外的信息。不过这正说明3 位或 6 位需要更高一层的结构来解决。第二步用捕获组让{1,2}作用于三位一组官方解法 solution.md 的巧妙之处在于颜色要么是 3 位要么是 6 位而 6 位恰好是两个连续的 3 位块。于是可以把3 位十六进制看成一组再用{1,2}表示这一组出现 1 次或 2 次let regexp /#([a-f0-9]{3}){1,2}/i;这里的关键就是捕获组capturing group。(...)把[a-f0-9]{3}包起来后量词{1,2}不再作用于最后一个字符而是作用于整个括号内容。这正是仓库 捕获组章节 开篇强调的括号两大作用之一在括号后放量词量词作用于括号整体。同理(go)匹配的是go、gogo、gogogo而go只匹配g后跟一串o(\w\.)\w则能匹配site.com、my.site.com这样的域名。本任务正是这套分组 量词思路的直接应用。加入g标志后测试let regexp /#([a-f0-9]{3}){1,2}/gi; let str color: #3f3; background-color: #AA00ef; and: #abcd; alert( str.match(regexp) ); // #3f3 #AA00ef #abc#3f3和#AA00ef都正确命中了但#abcd里的#abc也被匹配出来——这正是任务明确禁止的。原因在于正则默认从左到右扫描在#abcd的位置上前 3 位#abc已经满足3 位块出现 1 次引擎不会因为后面还有d就拒绝这个匹配。第三步用\b单词边界排除 4 位误匹配要拒绝#abc后面还跟着字母的情况需要在模式末尾加一个单词边界\blet regexp /#([a-f0-9]{3}){1,2}\b/gi; let str color: #3f3; background-color: #AA00ef; and: #abcd; alert( str.match(regexp) ); // #3f3 #AA00ef\b是一个零宽度测试不消费任何字符只在某个位置检查两侧是否恰好一边是单词字符\w拉丁字母、数字、下划线、一边不是。仓库的 单词边界章节 给出了三种满足边界的位置字符串开头且首字符是单词字符两个字符之间一个属于\w、另一个不属于字符串结尾且最后一个字符是单词字符。放到本任务中分析#3f3之后是分号3属于\w、;不属于边界成立匹配成功#AA00ef之后是分号同样成立#abcd中的#abc之后是d两边都是\w不构成边界于是整个候选被否决——引擎随后尝试把abcd完整当成 6 位块{1,2}中的 2 次但只剩 4 位凑不满 6 位最终该位置不产生任何匹配。这正是原任务 P.S. 强调的恰好 3 或 6 位的落地手段。类似地量词章节 中查找 5 位数字时用\b\d{5}\b排除更长数字与这里的思路完全一致。捕获组的副作用与进阶用法这个解法里的括号不仅让量词生效还会在匹配结果里留下捕获内容。仓库的 捕获组章节 详细说明了相关行为str.match(regexp)在不带g标志时返回数组result[0]是完整匹配result[1]、result[2]……依次是各捕获组内容括号按左括号从左到右编号嵌套时同样按左括号顺序带g标志时match只返回完整匹配列表不带组信息需要改用str.matchAll(regexp)才能拿到每个匹配的组内容。以本任务为例let regexp /#([a-f0-9]{3}){1,2}/i; let result #AA00ef.match(regexp); alert( result[0] ); // #AA00ef 完整匹配 alert( result[1] ); // ef 最后一组三位块的内容{1,2} 重复时组只保留最后一次result[1]是括号内最后一次参与匹配的 3 位块。如果只想让括号完成分组以应用量词这一件事、不想要这个多余的结果成员可以改用非捕获组(?:...)let regexp /#(?:[a-f0-9]{3}){1,2}\b/gi;这正是捕获组章节中Non-capturing groups with?:一节的用法需要括号让量词作用于整体但不需要在结果中单独看到它也无法在替换串中引用它。捕获内容在str.replace中还可通过$1、$2数字编号或$name命名组引用例如把颜色转成别的格式时可以直接拼装。如果想进一步校验整段字符串恰好是一个合法颜色而非在文本中搜索可以像 锚点章节 那样用^...$包围整个模式let colorRegexp /^#([a-f0-9]{3}){1,2}$/i; alert( colorRegexp.test(#abc) ); // true alert( colorRegexp.test(#ABCDEF) ); // true alert( colorRegexp.test(#abcd) ); // false alert( colorRegexp.test(#12345) ); // false对比可见在文本中搜索用\b划定边界对整串输入做格式校验用^...$锚定首尾二者场景不同不可混用。另外需要注意\b只认\w拉丁字母、数字、下划线对西里尔字母、中文等非拉丁字符组成的词不生效这是 单词边界章节 明确提示的局限。完整验证与实战封装将最终模式整合进一个可复用的函数并跑通任务给出的全部用例function extractColors(str) { let regexp /#([a-f0-9]{3}){1,2}\b/gi; return str.match(regexp) || []; } let str color: #3f3; background-color: #AA00ef; and: #abcd; console.log( extractColors(str) ); // [#3f3, #AA00ef] // 边界用例逐一核对 console.log( extractColors(a #12f b #1f2f3f c #xyz) ); // [#12f, #1f2f3f] —— #xyz 不是十六进制不匹配注意这里必须保留g标志没有g时match只返回第一个匹配无法取回全部颜色而extractColors返回空数组而非null方便下游直接遍历。小结这道练习浓缩了正则表达式三个相互咬合的核心概念官方解法见 solution.md字符类 精确量词[a-f0-9]{3}表达恰好 3 位十六进制数字详见 字符类 与 量词捕获组让量词作用于整体([a-f0-9]{3}){1,2}用3 位块出现 1 或 2 次优雅地表达3 位或 6 位这是 捕获组章节 的核心主题\b消除半截误匹配/#([a-f0-9]{3}){1,2}\b/gi确保#abcd中的#abc不被当作合法颜色详见 单词边界。同章节的姊妹练习 01-test-mac校验 MAC 地址01:32:54:67:89:AB与本任务思路相近但更强调全串校验适合作为进阶自测。掌握分组 量词 边界这一组合拳后类似恰好 N 或 M 位必须独立成词的匹配需求都可以照此拆解。赞分享文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载相关推荐正则表达式实战用捕获组与量词精确匹配 abc / abcdef 十六进制颜色正则表达式实战用捕获组与量词精确匹配 abc / abcdef 十六进制颜色 本文基于 Modern JavaScript Tutorial本仓库 9 re文档/教程前端用正则量词 {6} 匹配 HTML 六位十六进制颜色从 121212 到 AA00ef 的完整实战解析用正则量词 {6} 匹配 HTML 六位十六进制颜色从 121212 到 AA00ef 的完整实战解析 导读 在编写样式解析、主题提取、网页数据抓取等工具时文档/教程前端N_m3u8DL-RE 完整指南一键下载加密 DASH 流N_m3u8DL RE 完整指南一键下载加密 DASH 流 你手里只有一个 .mpd 链接课程却用了 CENC 加密页面能看不能存换三个工具都没跑通。NCLI音视频创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考