使用replace()与正则转换驼峰式时forEach替换异常问题
问题:正则替换实现驼峰命名时,为何只替换第一个匹配项?
我在Codewars完成编程题,需求是将字符串中的所有“-”和“_”转换为驼峰式命名。尝试用正则表达式实现,但在forEach循环中调用replace()时出现问题:每次循环中获取的目标字符是正确的,但替换后总是只替换第一个匹配项,请问这是为什么?
我的代码示例
var uniqueInOrder = function (str) { const reg = /[-_]\w/g; console.log(str.match(reg)); str.match(reg).forEach((el, i) => { console.log(el.charAt(1)); return (str = str.replace(reg, el.charAt(1).toUpperCase())); }); console.log(str); }; uniqueInOrder('the_stealth_warrior');
问题原因
- 全局替换逻辑错误:你的正则加了
g全局标志,但每次调用str.replace(reg, 固定字符串)时,会把所有匹配项一次性替换成同一个固定值,而不是只替换当前循环对应的那一个。比如第一次循环拿到_s,替换值是S,这时replace会把字符串里所有[-_]\w的匹配项都换成S,而非单个替换。 - 循环覆盖问题:
str.match(reg)会一次性获取所有匹配结果,但你在循环里每次都执行全局替换,每次替换都会覆盖之前的修改,最终只会保留最后一次循环的替换结果——把所有匹配项换成最后一个循环拿到的字符。
正确解决方案
不需要手动循环,直接利用replace的函数式第二个参数即可,这是实现驼峰命名的标准写法:
var toCamelCase = function(str) { // 匹配-/_后面的字符,用捕获组提取后转大写 return str.replace(/[-_](\w)/g, (match, capturedChar) => { return capturedChar.toUpperCase(); }); }; // 测试 console.log(toCamelCase('the_stealth_warrior')); // 输出 theStealthWarrior console.log(toCamelCase('the-stealth-warrior')); // 输出 theStealthWarrior
方案说明
- 正则
/[-_](\w)/g中的(\w)是捕获组,专门提取-或_后面的单个字符; - 当
replace的第二个参数是函数时,每匹配到一个结果就会调用一次该函数,函数的第二个参数就是捕获到的目标字符,直接转大写返回即可,自动完成全局替换。
内容的提问来源于stack exchange,提问作者Wojtek1911
相关产品推荐
相关产品推荐

