前端练习18 转换驼峰命名

知识点

  1. str.replace的用法,第二个参数的使用
  2. 正则表达式的使用

题目

编写toCamelCaseVar函数,将下划线格式的字符串替换成为驼峰式的字符串,例如is_good转换为isGood

变量名首尾的下划线不需要处理

实现

这道题目必然要用到的就是String.prototype.replace方法

str.replace(regexp|substr, newSubStr|function)

它的第一个参数可以使一个字符串,也可以是一个正则表达式,二个参数是要替换的字符串,或者是一个用来创建字符串的函数,这个函数的返回值将替换掉第一个参数匹配到的结果

在第二个参数中,可以引用前面匹配到的内容:

变量名 代表的值
$$ 插入一个"$"
$& 插入当前匹配的子串
$` 插入当前匹配的子串左边的内容
$’ 插入当前匹配的子串右边的内容
$n 插入当前匹配的第n个捕获组的内容

通过上面的特殊字符,可以在替换时应用前面匹配的内容。

当第二个参数是函数时:

function (match, p1, p2 ...)

它的第一个参数就是匹配的字符串,后续参数都是捕获组的内容

现在我们的需要是对匹配到的紧跟在_的字符需要变为大写,也就是说需要对匹配到的字符进行处理,这个时候第二个参数就不能是字符串了,因为如果使用字符串会是下面的格式:

'$1'.toLowerCase()

'$1'会被先被解析为字符串字面量,而不是当做一个特殊的模式。

所以第二个参数需要是一个函数

除此之外要注意,我们需要的是全局匹配,所以第一个参数后面要加上g修饰符

还有就是需要对开头的_的处理,我一开始正则总是想不到好的办法,所以索性在一开始将开头的_消除,最后处理完成后再加回来,所以我的第一种方法是:

const toCamelCaseVar = (variable) = > {
  const reg = /^_*/;
  // 匹配字符串开头的_
  const start = variable.match(reg);

  // 两步替换,第一步将开头的_消除
  // 第二步将其余的_消除,后面紧跟的字符放在捕获组p1中,转换为大写
  let result = variable.replace(reg, '').replace(/_+(.)/g, (match, p1) = > p1.toUpperCase());
  
  // 如果之前消除过开头的_,需要加回来
  if (start && start.length > 0) {
    result = start[0] + result;
  }
  return result;
};

也不是特别复杂,这里面第二步的正则替换是以_a这个形式进行的,参考了一些别人的答案,确实还有更简单的实现方式

第二种方法

这种方法用一个正则就可以搞定,不过这次的正则替换是以x_a这个形式进行,要求开头和结尾的_不处理,也就是说,要处理的_前后一定至少有一个字符,而且后面的字符是要转换为大写的

所以,正则表达式如下:

/([^_])(_+)(.)/
  • p1就是上面的x,它匹配任何不是_的字符
  • p2是要消除的_,它的数量应该是≥1的
  • p3是后面跟随的字符,需要转换为大写

所以这个匹配到字符串就需要调换为p1 + p3.toUpperCase()

const toCamelCaseVar = (variable) => variable.replace(/([^_])(_+)(.)/g, (match, p1, p2, p3) => p1 + p3.toUpperCase());

补充

另外,还有一个知识点,如果要消除()分组后被缓存为捕获组的影响,可以在()开头加上?:,就不会被缓存了

参考

  • #29 转换驼峰命名@ScriptOJ
  • String.prototype.replace()@MDN
  • 正则表达式 - 语法@runoob

你可能感兴趣的:(前端练习)