ARTICLE DETAIL

资讯详情

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

freeCodeCamp Daily Coding Challenge 284:用正则实现 “I Before E Except After C“ 拼写校正

freeCodeCamp Daily Coding Challenge 284:用正则实现 “I Before E Except After C“ 拼写校正 freeCodeCamp Daily Coding Challenge 284用正则实现 I Before E Except After C 拼写校正【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp导读本文围绕 freeCodeCamp 开源仓库中curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbd.mdChallenge 284: I Before E展开完整拆解这道字符串处理编程题的题目规则、5 组测试用例、JavaScript 与 Python 双语言官方参考解法并结合仓库中 daily coding challenge 体系的配套代码块结构定义、成对校验测试、种子脚本与前后端组件讲清它在整个项目中的落地方式。读完本文你将掌握一类基于相邻字符上下文做字符串替换问题的分析与实现方法并理解 freeCodeCamp 的每日编程挑战从题库到测试再到数据播种的完整链路。一、题目背景什么是 freeCodeCamp Daily Coding ChallengeDaily Coding Challenge每日编程挑战是 freeCodeCamp 平台上一套按天更新、题型短小的编程练习。在本仓库中它们以课程块block的形式存在于 Dev Playground 超级块下包含 JavaScript 与 Python 两套平行实现块定义见 curriculum/structure/blocks/daily-coding-challenges-javascript.json共 365 道JavaScript 版与其 Python 对应块每个块的元数据记录了isUpcomingChange、usesMultifileEditor、helpCategory: JavaScript、disableLoopProtectTests以及challengeOrder中按id排序的全部挑战标题从 curriculum/src/test/daily-challenges.test.js 的校验逻辑可以看到系统要求 JS 与 Python 两个块的挑战数量完全相等、id 完全一致且非英语环境以外还要求标题与描述逐一匹配——Challenge 284 正是同时存在于两个块中的一题JS 版challengeType: 28Python 版challengeType: 29。Challenge 284 排在挑战序列的第 284 位紧随 Challenge 283 String Zipper紧邻 Challenge 285 Meeting Time是 365 道挑战中后段的一道字符串处理题。二、题目规则I before E except after C原题描述如下Given a word or sentence, return a corrected version where every word follows the I before E except after C rule.它要求我们把一句英语中不符合 I before E except after C 拼写习惯的词改回正确拼写具体规则只有三条如果单词中包含ei且其前面不是c则把它替换成ie例如beleive→believe如果单词中包含ie且其前面是c则把它替换成ei例如recieve→receive其余所有单词保持不变。需要注意的是规则 1 的前面不是 c与规则 2 的前面是 c互为补集因此任何出现ei或ie连续字符的单词都会命中其中一条规则不包含这两个连续字符的单词则原样返回。三、测试用例五组输入输出题目通过 5 个断言hints定义验收标准它们也是仓库中实际运行的测试输入预期输出覆盖点beleivebelieve单次ei前非 c→ierecievereceive单次ie前为 c→eiwe recieved a breifwe received a brief多词句子、大小写保持、非命中词a不变she beleived the friendly niece could percieve the greifshe believed the friendly niece could perceive the grief一句中同时出现ei→ie与ie→ei两类修正we recieved relief after the theif gave us a breif piece of feirce deceitwe received relief after the thief gave us a brief piece of fierce deceit单词内部可多次命中、deceit中cei反向验证、relief/thief/grief等正向验证最后一组用例特别值得注意deceit本就是ceic 后跟 ei它是正确的拼写不应该被改坏而recieved、theif、breif、feirce都属于错误拼写需要逐一纠正。它同时验证了函数不会对正确的cei造成破坏性修改。测试断言的写法因语言而异JavaScript 版直接使用assert.equal(iBeforeE(...), ...)参见 JS 挑战文件Python 版通过runPython内嵌unittest的TestCase().assertEqual(...)参见 Python 挑战文件。四、起始代码与解题思路题目给出如下的函数骨架seed学习者需要填充实现function iBeforeE(sentence) { return sentence; }Python 版对应骨架def i_before_e(sentence): return sentence核心难点在于如何精确表达ei 前面不是 c。直接查找子串ei会误伤recieve这类cie结构——因为其中也包含eirec-i-ei-ve中...cei...的ei前面正是c。因此必须借助前向上下文来判断。解题思路可以分三步用split( )把句子按空格拆成单词数组题目用例中单词间均为单个空格对每个单词应用两条替换规则重新用空格拼接保持原句结构不变。五、官方解法JavaScript 正则版本仓库中 JS 版官方参考解法如下function iBeforeE(sentence) { return sentence.split( ).map(word { word word.replace(/([^c])ei/g, $1ie); word word.replace(/cie/g, cei); return word; }).join( ); }逐行解读sentence.split( )按单个空格切分句子word.replace(/([^c])ei/g, $1ie)正则([^c])ei匹配一个非 c 字符紧跟着 ei的组合g标志确保单词内所有命中位置都被处理。([^c])是捕获组$1ie表示把捕获到的那个字符原样保留、再把ei换成ieword.replace(/cie/g, cei)把ciec 后接 ie整体替换为cei.join( )把修正后的单词重新拼回句子。两次替换的顺序是安全的第一次替换后所有非 c 前缀的ei已变为ie剩余的ei只可能以cei形式存在此时cie也就只可能来自原本的ci后接ei即cie原形因此第二次替换不会误伤。以we recieved a breif为例走一遍拆分为[we, recieved, a, breif]we无ei/ie不变recieved第一次替换[^c]ei需要非 c 前缀recieved中的ei位于c之后re-ci-ei-ved不匹配第二次替换cie→cei得到receiveda不变breif第一次替换([^c])ei中[^c]捕获r$1ie得到brief第二次替换无命中拼接回we received a brief与断言一致。六、官方解法Python 正则版本Python 版参考解法使用了re模块import re def i_before_e(sentence): words [] for word in sentence.split( ): word re.sub(r([^c])ei, r\1ie, word) word re.sub(rcie, cei, word) words.append(word) return .join(words)与 JS 版一一对应re.sub(r([^c])ei, r\1ie, word)等价于replace(/([^c])ei/g, $1ie)\1即 JS 中的$1re.sub(rcie, cei, word)等价于replace(/cie/g, cei)。JS 用map返回新数组Python 用显式words.append累积结果逻辑完全同构。七、边缘情况与隐藏陷阱分析结合题目与解法有几个值得注意的边界ci后跟ei的正确词不可被改坏如deceit、ceiling。它们命中第二条规则cie→cei不会——它们本身是cei不含cie第一条规则要求[^c]ei而它们的ei前缀是c因此两次替换都不命中保持不变符合规则 3多词句子与标点本题用例只出现空格分隔、无标点的单词。若单词带句号/逗号如breif,([^c])ei的[^c]也能匹配非 c 字符仍可正确修正但把ei出现在词首如专有名词Eiffel的情况不在本用例覆盖内大小写[^c]只匹配小写c/cie/同样区分大小写因此大写Cie结构不会被处理。本题用例均为小写重叠命中g标志与re.sub默认替换全部非重叠命中。像theif中ei前后分别是h和f一次性替换即可像feirce中ei前为f被第一条规则修正后ce结构不再构成cie不会产生二次误伤。这些边界正是基于上下文的正则替换类题目的通用考察点写正则时永远要思考零宽断言与捕获组的取舍、替换顺序对重叠模式的影响以及替换是否会破坏已经正确的子串。八、在仓库中的落地从题库到线上Challenge 284 并非孤立的一页文档它嵌入在完整的 daily coding challenge 工程链路中题库与测试挑战正文、断言与种子代码以 Markdown 前奏frontmatterid/challengeType/dashedName存储在 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/ 与同名的 Python 块目录下由课程 schema 校验工具curriculum/schema/challenge-schema.js检查格式合法性成对校验curriculum/src/test/daily-challenges.test.js 通过getChallenges加载 Dev Playground 超级块断言 JS 与 Python 两个块挑战数相等、id 一一对应、测试数一致保证双语言题库不漂移后端服务api/src/daily-coding-challenge/ 提供获取每日挑战信息的 Fastify 路由与 schemaroutes、schemas、utils 三个子目录含配套单测其 README 说明每日挑战的提交仍走 API 主体部分前端组件client/src/components/daily-coding-challenge/ 提供calendar每日日历、widget、not-found等组件含calendar.test.tsx呈现每日一题入口数据播种tools/daily-challenges/ 下的seed-daily-challenges.ts与 README 说明了完整流程复制sample.env为.env、启动开启即将上线的更改的客户端以从 GraphQL 拉取挑战、在tools/daily-challenges目录运行pnpm seed-daily-challenges最终把 Dev Playground 超级块中的挑战写入freecodecamp数据库的DailyCodingChallenges集合。也就是说一道 Challenge 284 从 Markdown 题目出发经由 schema 校验、双语言配对测试、GraphQL 提取与播种脚本最终成为平台上可被每日调度的真实练习。九、举一反三同类问题的扩展练习掌握了本解法的模式后可以尝试以下变体巩固扩展到任意上下文规则把前一个字符推广为前两个字符例如将ckei特殊处理只需把正则写成([^c])ei的变体如(..)ei加回溯约束用零宽断言重写word.replace(/(?!c)ei/g, ie)使用后行断言lookbehind能更直观地表达前面不是 c是 JS 2022 / PythonrePython 3.6 可变长度后行支持的可选写法但注意cie情形仍需第二次替换兜底处理标点与大小写尝试先提取纯字母 token 再修正最后还原标点与大小写使函数能处理带句号、逗号、首字母大写的真实文本。结语Challenge 284 I Before E 是一道教科书级的正则字符串处理题规则简洁却要求对捕获组、全局替换与替换顺序有准确理解。它在 freeCodeCamp 仓库中的完整呈现JS/Python 双语言、5 组断言、schema 校验、成对测试、播种脚本也为学习者展示了一个真实开源项目中一道编程题从文档到线上的标准工程化路径。建议结合上述源码路径逐一阅读把题目本身与它所在的工程链路一起消化。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表