牛客网 前端技能测评挑战 做题详解
正则表达式yyds!!! 正则的专题
FED2 获取 url 参数
使用正则表达式将参数抽取出来:
"http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe".match(/(\w+)=(\w+)/g)
// ["key=1", "key=2", "key=3", "test=4"]
由于题目需要指定参数,那么:
"http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe".match(/(key)=(\w+)/g)
// ["key=1", "key=2", "key=3"]
"http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe".match(/(test)=(\w+)/g)
// ["test=4"]
‘key’ 和 'test’要如何切换?使用正常的正则写法没办法设置变量,那么就 涉及到一个如何给正则表达式里面设置变量的问题:
解决办法是:使用new RegExp("…")
let reg = /(key)=(\w+)/g
let str = 'key'
let reg2 = new RegExp('('+str+')=(\\w+)','g') // reg2 = /(key)=(\w+)/g
//这里效果和reg是一样的。注意\w+前面还需要一个斜杆 \ 作为转义字符。正常的/(key)=(\w+)/g书写是不用的。
题解:
function getUrlParam(sUrl, sKey) {
if(sKey){ // 如果参数被指定了,即 sKey 存在
let reg = new RegExp('('+sKey+')=(\\w+)','g')
let arr = sUrl.match(reg)
// 如果匹配成功,返回的arr是个数组,里面存的是 ["key=1", "key=2", "key=3"]之类的数据,
// 如果匹配不到东西,返回的是null
if(arr){ // 如果arr存在,不是null
let arr02 = arr.reduce((acc, cur)=>{ // 遍历arr,
acc.push(cur.split('=')[1]) // 将每一项字符串分割开,右边的值存入数组中返回
return acc
}, [])
if(arr02.length === 1){// 如果返回的数组的值只有一项,那么直接返回这个值
return arr02[0]
}else{ return arr02 }// 如果返回的数组的值大于一项,那么直接返回这个数组
}else{ return '' } // 如果arr是null,没匹配到如何信息,那么返回空字符串
}else{// 如果参数没有指定了,即 sKey不存在,是undefined
let reg2 = /(\w+)=(\w+)/g
let arr = sUrl.match(reg2) // 这里可以抽取所有的属性了,不需要用变量指定
if(arr){ // 如果arr存在,不是null
let obj01 = arr.reduce((acc,cur)=>{ // 遍历arr,
let arrcur = cur.split("=")
if(!(arrcur[0] in acc)){
// 如果累加器的acc {...}里面已经存在这个属性了,即之前已经初始化过为数组了,那么忽略掉,直接下面添加;
// 如果不存在该属性,要先将这个属性的值初始化为一个数组
acc[arrcur[0]] = []
}
// 如果累加器的acc {...}里面已经存在这个属性了,即之前已经初始化过为数组了,那么忽略掉,直接用push添加元素;
acc[arrcur[0]].push(arrcur[1])
return acc // 累加器每一轮都得返回的。
},{})
return obj01
}else{ return {} }// 如果arr不存在,正则没有匹配到任何东西,返回空对象
}
}
FED9 邮箱字符串判断
正则表达式yyds!!!
题解:
正则: /^\w+[.\w]*[a-z\d]+@[a-z\d]+(.\w+)+$/i
FED11 将字符串转换为驼峰格式
题解:
题解中有四个方法:sName.slice(1)
、word.substring(1)
、word.toUpperCase()
、sName.replace(...)
1、sName.slice()
:切片,数组也有这个同名的方法。
slice() 方法提取某个字符串的一部分,并返回一个新的字符串,且不会改动原字符串。
str.slice(beginIndex[, endIndex])
beginIndex: 从该索引(以 0 为基数)处开始提取原字符串中的字符。如果值为负数,就从倒数的开始:"the lazy dogg".slice(-4); // "dogg"
endIndex: 切片不含这个尾部,如:"the lazy dogg".slice(0, 2); // "th"
2、word.substring()
: 也算是切片方法,常用来截取字符串,并返回一个新的字符串,且不会改动原字符串。
str.substring(indexStart[, indexEnd])
用法:"the lazy dogg".substring(0, 2); // "th"
、 "the lazy dogg".substring(2); // "e lazy dogg"
3、word.toUpperCase()
: 转大写,括号里不用写参数,返回新字符串,且不会改动原字符串。
用法:"The lazy dogg".toUpperCase(); // "THE LAZY DOGG"
4、sName.replace(...)
: 替换, 返回新字符串,且不会改动原字符串。
str.replace(regexp|substr, newSubStr|function)
用法:
(简易版)第一个参数是substr —— 一个将被 newSubStr 替换的 字符串
“The lazy lazy dogg”.replace(‘lazy’, 2233); // “The 2233 lazy dogg” 仅第一个匹配项会被替换。
(正则版)第一个参数是regexp —— 一个RegExp 对象或者其字面量。该正则所匹配的内容会被第二个参数的返回值替换掉。
第二个参数是函数function —— 一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果。注意:如果第一个参数是正则表达式,并且其为全局匹配模式,那么这个方法将被多次调用,每次匹配都会被调用。
用法:(这里的 \b 意思为匹配一个字符串的边界,比如字符串的最开头,,以及空格等)
FED10 颜色字符串转换
reg = /^rgb(\d{1,3},\s*\d{1,3},\s*\d{1,3})$/
正则书写的注意点:
1、括号要用斜杠 \ 转义,两边的括号都要转义;
2、空格( \s )题目要求是可有可不有,出现0次或多次,用 * 而不是 + ;
3、\d{1,3} 代表的是数字( \d )是1/2/3位都可以,不出现数字或4位数5位数以上就不行。
用 /^rgb(\d{1,3},\s\d{1,3},\s\d{1,3})$/g.test(sRGB);** 检测是否符合标准
用 let arr = sRGB.match(/\d{1,3}/g); 抽取里面的三个数字
抽取出来后放入数组arr中 ,一个个遍历。数组中存的是字符串,需要将其转换回十进制数字,判断数字是否大于 255才能继续。
用 let num = parseInt(arr[i],10); 转换
数字符合小于等于255条件后,利用toString(16)方法 将10进制(数字)转换为16进制(字符串)
一个踩坑点:
Number的toString方法,字符串不能转,比如 console.log(‘123’.toString(16) ); // ‘123’
只能 console.log((123).toString(16) ); // “7b”
let str16 = num.toString(16)
题解:
FED60 判断是否符合 USD 格式
正则表达式yyds!!!
题解: