“ 今天说说正则吧,平时用到的时候不少,但是可能大部分人都是直接搜索吧?“谁没事花时间写这个呢?直接搜索不香吗?”,你自己或者同事有没有这样说过呢? ”
首先得了解基本的匹配规则,这里就不说了,网上资料非常多,大家自行查找。
然后看看什么是子项,先从一道AL面试题来分析:
说明:写一个转换函数,把json对象的key值从下划线(Pascal)形式转为小驼峰(Camel)形式 示例:convert({“a_bc_def”: 1}); // 返回 {“aBcDef”: 1}
分析:此题的考点是replace方法,和正则表达式
先举个栗子,看看这个方法怎么用:
var str = "a_bc_def"
function toCamel (str) {
return str.replace(/_\w/g, function (a, b, c, d) {
console.log(a, b, c, d)
})
}
toCamel(str)
结果:
_b 1 a_bc_def undefined
_d 4 a_bc_def undefined
分析:
参数 a 代表 匹配到的字符串 参数 b 代表 匹配到的字符串的下标 参数 c 代表 整个字符串 至此,此题已经可解 但是,匹配到字符串中还有下划线,此时还不是最优解,能不能直接匹配到首字母呢
答案是肯定的,先看效果,换一种写法
var str = "a_bc_def"
function toCamel (str) {
return str.replace(/_(\w)/g, function (a, b, c, d) {
console.log(a, b, c, d)
})
}
toCamel(str)
结果:
_b b 1 a_bc_def
_d d 4 a_bc_def
分析:
参数 a 代表 匹配到的字符串 参数 b 代表 匹配到的没有下划线的字符串 参数 c 代表 匹配到的字符串的下标 参数 d 代表 整个字符串 不同的地方,就是多写了个括号,下面来看看这个括号是个什么东西
正则表达式的子项(子表达式)
没错了,每个()中包含的部分叫做正则的子项(子表达式)
为了看明白,改一下上面的栗子,给下划线也加上括号,看看效果
var str = "a_bc_def"
function toCamel (str) {
return str.replace(/(_)(\w)/g, function (a, b, c, d, e) {
console.log(a, b, c, d, e)
})
}
toCamel(str)
结果:
_b _ b 1 a_bc_def
_d _ d 4 a_bc_def
分析:
现在参数变成5个了 参数 a 代表 匹配到的字符串 参数 b 代表 匹配到的下划线 参数 c 代表 匹配到的没有下划线的字符串 参数 d 代表 匹配到的字符串的下标 参数 e 代表 整个字符串
由上,可以发现规律:
第1个参数表示: 匹配到的字符串 第2个参数表示: 匹配到的字符串的第1个子项 第3个参数表示: 匹配到的字符串的第2个子项 ……如果有多个子项,则依次类推 然后倒数第2个参数是:匹配到的字符串的下标 最后1个参数是:整个字符串
至此,分析完毕
此题解法是
var obj = {"a_bc_def": 1}
function toCamel (a) {
return a.replace(/_(\w)/g, function(a, b){
return b.toUpperCase()
})
}
function convert (obj) {
if (Object.prototype.toString.call(obj) !== '[object Object]') return obj
let res = {}
for (key in obj) {
let newKey = toCamel(key)
res[newKey] = obj[key]
}
return res
}
console.log(convert(obj)) // {aBcDef: 1}
拓展
replace的第二个参数可以是字符串,也可以是函数。如果它是字符串,那么每个匹配都将由字符串替换。 但是 replacement 中的 $ 字符具有特定的含义。如下表所示,它说明从模式匹配得到的字符串将用于替换。
字符 | 替换文本 |
---|---|
2、...、$99 | 与 regexp 中的第 1 到第 99 个子表达式相匹配的文本。 |
$& | 与 regexp 相匹配的子串。 |
$` | 位于匹配子串左侧的文本。 |
$' | 位于匹配子串右侧的文本。 |