面试官:这么简单的正则表达式都不会?

正则表达式有多神奇

最近发现很多的面试和笔试中都经常出现正则表达式相关的题目,面试官:这么简单的正则表达式都不会?面试者:嘴角微微上扬,回以一个不失礼而尴尬的笑

熟练掌握正则表达式,不仅能够在面试中体现编程水平,在平时的开发过程中也能够用于优化我们的代码,让我们写出更加精炼的语句
这不就是老鸟装ABCDEFG之道吗,
在CodeReview的时候假装不经意间写出一条老长老长的正则表达式,丢到新鸟面前,云淡风轻得说一句,这不就简简单单一条正则就能解决吗,写这么多代码干嘛?

回到正题,最近这段时间重新学了下正则表达式,还是发现正则表达式有很多值得学习的地方,今天我就通过这篇文章记录一下自己学习正则表达式的笔记,也希望能够分享给大家,一起快乐搬砖!

正则表达式 VS 循环+判断

先来举个例子,题目是这样子

    给出两个字符串 str 和 sub,你的任务是在 str 中完全删除那些在 sub 中存在的字符。
    注:字符串包含空格,1≤len(str),len(sub)10^5

    输入:  
    str="I am YimWu",sub="abc"
    输出: 
    "I m YimWu"

循环+判断

我们来看一下,作为不知道正则表达式的小白,我们该怎么处理呢?万物皆可循环,这个时候我们祭出祖传“循环+判断”王炸组合

let CharacterDeletion = (str, sub) => {
  // 剔除字符串中所有的目标字符
  let replaceFun = (replaceStr,char) => {
    // 用于保存剔除操作后的字符串
    let r = replaceStr
    // 若没有找到对应字符则返回原字符串
    if(r.indexOf(char) == -1){
      return r
    }else{
      // replace匹配到第一个字符并剔除
      r = r.replace(char,'')

      // 剔除后再次检查是否还有需要剔除的字符
      // 无则返回,有则递归调用原函数
      if(r.indexOf(char) == -1){
        return r
      }else{
        return replaceFun(r, char)
      }
    }
  }
  let r = str
  sub.split('').forEach(ele => {
    r = replaceFun(r, ele)
  });
  return r
}

// 输出返回
console.log(
  CharacterDeletion('I am YimWu', 'aeiou') // result => I m YmW
)

到这里总算憋屈地把结果写出来了,虽然代码量不算很多,但是由于 node 环境中不支持replaceAll (Version>85的chrome支持),所以只能用递归来完成replaceAll的功能,所以代码的可读性随即降低了很多,这里可能还有其他的解法,就不一一展示了,有兴趣的小伙伴可以留言区交流交流

正则表达式

说完了上面憋屈的解法,我们来看看使用正则表达式的写法

// 字符串过滤
let CharacterDeletion = (str, sub) => {
  // 利用eval动态拼接正则表达式
  let reg = eval(`/[${sub}]/g`)
  return str.replace(reg, '')
}

// 输出返回
console.log(
  CharacterDeletion('I am YimWu', 'aeiou') // result => I m YmW
)

OhMyGod!!!快,块扶我起来,我想学习!!

显而易见,对于第一种方法需要十几二十行代码才能解决的问题,利用正则表达式5行就可以直接解决,不仅代码量大大减少了,而且代码的可读性也提高了不少,所以还不快来跟我学一学这欲罢不能的正则表达式

正则表达式有哪些用法

正则表达式的用法有很多,但是平常我们工作中,面试中用到的大部分都是正则表达式的基础用法,所以今天主要以介绍基础的用法为主,如果需要更加系统,深入的学习正则表达式,可以阅读文末参考书籍、文章进行学习

正则的匹配方式

按生活经验来说,我们都知道,如何事情,都有相对的两面,那么,正则表达式其实也一样,正则表达式也有两种相反的匹配方式,举两个实际应用的例子:

正向匹配——匹配与表达式相符的内容

我们在用 webpack 打包时需要让 webpack 知道,什么文件用什么 loader 进行解析,那么我们需要在 webpack 的 module.rules 中写入匹配的正则表达式,匹配特定的文件后缀名,如 /\.vue/,这个表达式的作用是,匹配所有以 .vue 结尾的文件,这就是正向匹配

反向匹配——匹配与表达式不相符的内容

我们都知道前端安全问题主要集中在登录框、留言框以及各种接受输入的位置,那么作为前端,我们该如何防范呢,其中有一个比较有效的便是正则表达式的反向匹配。

前端最常见的攻击有两种,一种是xss攻击,另一种是注入攻击,两种攻击最基础的防范方式就是利用正则表达式,排除特殊字符(如<>|等),达到屏蔽部分攻击的可能

例如:

/[^%--`~!@#$^&*()=|{}':;',\[\]\.<>]/

这就是摘抄了某系统的过滤语句(不一定严谨),该语句匹配不符合的,才是前端允许输入的内容

正则表达式相关方法

const str = 'abc'
// test 验证是否满足正则表达式,返回 true/false
str.test(/[a-z]/)
// match 返回正则表达式匹配结果 返回数组
str.match(/[a-z]/)

正则表达式匹配字符

元字符
字符含义
\d[0-9]/表示0-9其中一位
\D[^0-9]/表示除了0-9之外的任意字符
\w[0-9a-zA-Z_]/表示数字、字母以及下划线
\W[^0-9a-zA-Z_]/表示非单词、字母以及下划线
\s[\t\v\n\r\f]/表示各种空白符号,空格、制表符等
\S[^\t\v\n\r\f]/表示非空白字符
.[^\n\r\u2028\u2029]/表示除了换行符、回车符、行分隔符和段分隔符之外的字符
数量以及范围字符
字符含义
+{1, }/表示至少需要出现一次
*{0, }/表示出现任何次,包含不出现
?{0,1}/表示不出现或者出现一次
{m, }至少出现 m 次
其他字符
字符含义
|表示分支,/a | b/, 表示a或b
^在开头表示匹配以某字符开头,在字符集中表示反向匹配
$在末尾表示匹配以某字符结尾
|表示分支,/a | b/, 表示a或b
/RegExp/ ii 即 ignore,表示匹配时忽略大小写
/RegExp/ gg 即 global,表示全文匹配

正则表达式实践例子

上面列了几个表格,把基本用法都罗列了一遍,理论已经到位,那么接下来就举一些我平时工作中具体的例子,看看如何利用这些字符,通过排列组合,实现灵活多变的需求吧!

匹配信息中的手机号码
// \d 表示匹配数字,{11}表示匹配11位
const str = 'yimwu: 19448751214'
str.match(/\d{11}/)
webpack loader 配置中,匹配所有的vue文件
// \. 表示转义,vue$ 表示以 vue 结尾,即 vue 相关的源文件
const fileName = 'app.vue'
const reg = /\.vue$/
reg.test(filename)
只允许上传 png 和 jpg 格式的图片
const reg = /(\.png$)|(\.jpg$)/
const uploadFileName = 'pic.png'
reg.test(uploadFileName)
匹配十六进制颜色
// 颜色由 #开头,加上3、6位16进制数组成
const reg = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/
reg.test('#c8c8c8') // true
匹配日期
// {4}量词前表示匹配年份
// (0[1-9]|1[0-2]) 匹配的是月份 01-12
// (0[1-9]|[12][0-9]|3[01]) 这里需要特别注意的是需要分情况匹配,若开头为3,则只有30/31满足匹配
const reg = /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/
reg.test("2022-03-22")

写在最后

这篇文章算是一个正则表达式非常基础的入门篇吧,所涉及的正则表达式的内容也非常有限,只是以我平时的实际例子作为引子,希望能够给想了解正则表达式的朋友们做个简单的浏览,如果想更进一步系统的学习正则表达式,请阅读以下参考文章,各位前辈大佬们已经总结得很精辟了,大家可以移步拜读拜读!

相关链接

JS正则表达式完整教程(略长)[强烈推荐]
学会正则很简单,前端大佬悉心整理的正则表达式笔记
三十分钟包会——正则表达式

求关注

该专栏将持续更新前端相关技术的整理与总结,欢迎订阅!
如果喜欢博主的文章,那就狠狠给博主点个赞呗,让我们一起成长吧!
欢迎关注博主文章首发号 掘金社区,转发记得私信博主哟哟!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值