共计 3276 个字符,预计需要花费 9 分钟才能阅读完成。
正则
引言
正则是一个前端必须掌握的知识。但是由于用的少,忘了记,记了忘,导致面试经常坐蜡。这里上篇先介绍正则的规则,下篇结合一些具体题目,带大家重新学习巩固一下正则,争取面试给自己加分。
面试题实战
1. 匹配汉字
let regx = /^[\u4e00-\u9fa5]{0,}$/
2. 中国真实姓名
let reg = /^[\u4e00-\u9fa5]{2,4}$/
3. 字符串去重
把 aaabbbccc 变成 abc
思路 1,转换成数组,利用 set 去重,再 join
思路 2,正则(有局限性,必须是重复元素挨一起的,且不是这种镶嵌的 ’abac’)
let a = 'aabbbccc'
let b = a.replace(/(\S)\1+/g,function (res) { // 这里 \1 指的是第一个分组
return res[0]
})
console.log(b) //'abc'
4. 转驼峰
var s1 = “get-element-by-id”; 给定这样一个连字符串,写一个 function 转换为驼峰命名法形式的字符串 getElementById
let a = 'get-element-by-id'
// 这个题目如果想分割单词是比较麻烦的
let f = function(s) {return s.replace(/-\w/g, function(x) {return x.slice(1).toUpperCase();})
}
console.log(f(a)) //getElementById
5. 日期格式化
2017-05-11 转换成 5 /11/2017
let a = '2017-05-11'
let reg = /(\d{4})-(\d{2})-(\d{2})/g
b=a.replace(reg,function (res, g1, g2, g3) {return `${g2.slice(1)}/${g3}/${g1}`
})
console.log(b) //5/11/2017
6. JS 实现千位分隔符
var a = '1234567'
var reg = /\d{1,3}(?=(\d{3})+$)/g
var b = a.replace(reg,function (res,group,index) { // 如果有?的话分组指的是最后一个
console.log(res,group,index) // 所以 group 永远是 4,5,6
return res + ','
})
console.log(b) //1,234,567
7. 获取 url 中的参数
let url = 'www.baidu.com?age=11&name=fyy'
let reg = /([^?&=]+)=([^?&=]+)/g
var obj = {}
url.replace(reg,function(){obj[arguments[1]] = obj[arguments[2]]
})
console.log(obj)
8. 验证身份证号
身份证号码可能为 15 位或 18 位,15 位为全数字,18 位中前 17 位为数字,最后一位为数字或者 X
let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
9. 句子去重复单词
“Is is the cost of of gasoline going up up”=> “”is the cost of gasoline going up””
let a = 'Is is the cost of of gasoline going up up'
let reg = /\b([a-z]+) \b\1/ig
// 注意不能写成这样 let reg = /(\w)+ \1/ig 匹配单个字符是错的,只会匹配到最后一个
//(\w+) \1/ig 这么写也行
let b = a.replace(reg,function (res) {return res.split(' ')[0]
})
console.log(b) // Is the cost of gasoline going up
10. 写一个方法使得数字末尾的连续 0 变成 x 如 0001230000 变成 000123xxxx
var a = '0001230000'
var b=a.replace(/(\d)\1+$/ig,function(res){return res.replace(/0/g,'x') //replace 改变不了原字符串
})
console.log(b) //000123xxxx
11. 有效数字验证:整数负数 0 小数
. 可以出现可也以不出现,但是一旦出现后面必须跟一位或者多位数字
最开始可以有 +/- 也可以没有
整数部分,一位数可以是 0 -9,多位数不能以 0 开头
let reg = /^-?(\d|([1-9]\d+))(\.\d+)?$/
12. 字符整体替换
将 ’20151214’ 转化为繁体 ’ 贰零壹伍壹贰壹肆 ’
var str = '20151214'
var ary = ['零','壹','贰','叁','肆','伍']
str =str.replace(/\d/g,function () {return ary[arguments[0]] // 参数的第一个元素就是匹配的内容
})
console.log(str) //-> 贰零壹伍壹贰壹肆
13. 出现字符最多的次数
let str = 'zzzzzzzzzguowoaini'
let obj = {}
str.replace(/[a-z]/ig,function () {let val = arguments[0]
obj[val] >=1?obj[val]+=1:obj[val] =1
})
let max = 0
for(let key in obj){obj[key]>max?max=obj[key]:null
}
console.log(max) //-->9
14. 搜索高亮功能的正则分割
现在我要做一个搜索 高亮
功能,需要一个拆分的正则来筛选出需要高亮的文本/比如我输入 1,我需要 ’ 账户 A 同步 B 121’ 拆分成这个数组[‘账户 A 同步 B’,’1′,’2′,1′] 前面的 1 和后面的 1 都要高亮
let reg = /(?<=1)|(?=1)/g
'账户 A 同步 B 121'.split(reg)
//["账户 A 同步 B", "1", "2", "1"]
15. pug 模版引擎的基本原理
我们选用一个经典的模版引擎 pug, 进入它的入门指南,pug.compileFile 根据传入的字符串模版,生成了一个方法 compiledFunction,compiledFunction 根据传入的数据参数,生成不同的 html 代码。问题来了,怎么实现 compiledFunction 这个函数?
//- template.pug
p #{name}的 Pug 代码!const pug = require('pug');
// 编译这份代码
const compiledFunction = pug.compileFile('template.pug');
// 渲染一组数据
console.log(compiledFunction({name: '李莉'}));
// "<p> 李莉的 Pug 代码!</p>"
// 渲染另外一组数据
console.log(compiledFunction({name: '张伟'}));
// "<p> 张伟的 Pug 代码!</p>"
分析:compileFile 这个函数接受一个对象参数,根据属性值,执行相应的正则替换
function compiledFunction (args) {let template = 'p #{age1}的 Pug 代码!'
// 第一步,先生成标签 <p>{name}的 Pug 代码!<p/>
let a = template.replace(/^([a-z]) (.+)/g,function () { //\S 没办法匹配空格,. 可以
return `<${arguments[1]}>${arguments[2].slice(1)}<${arguments[1]}/>`
})
// 第二步,再替换内容
a = a.replace(/{(.+)}/g,function (pat,group1) {return args[group1]
})
console.log(a) //<p>fyy 的 Pug 代码!<p/>
}
compiledFunction ({age1:'fyy'}) //<p>fyy 的 Pug 代码!</p>