最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端必会-快速掌握正则表达式

    正文概述 掘金(greet_eason)   2021-04-01   534

    前端必会-快速掌握正则表达式

    1.前言

    提到正则,可能很多人会和我以前一样,第一时间会感到很头疼,此篇文章的目的不在于让大家变成正则高手,仅仅只是叙述一些简单正则的写法如何写一些简单正则,一起加油吧!

    2.正文

    2.1 福利章节

    首先放出写正则的常用API表,毕竟作为一个api工程师,看api很重要!

    前端必会-快速掌握正则表达式

    前端必会-快速掌握正则表达式

    前端必会-快速掌握正则表达式

    前端必会-快速掌握正则表达式

    前端必会-快速掌握正则表达式

    API表看完,我们正则就学会了一半了!

    2.2 认识模糊匹配

    正则的精确匹配意义不大,大部分是模糊匹配,其中有两种方式:横向和纵向匹配 1.横向匹配

    // 表示匹配:第一个字符是 "a"
    // 接下来是 2 到 5 个字符 "b",
    // 最后是字符 "c"。
    const r = /ab{2,5}c/
    

    2.纵向匹配

    // 此时可以匹配'a1b'或者'a2b'或者'a3b'
    const r = /a[123]b/
    

    既然学了,那么肯定是为了能用到,那么此时我们可以做哪些事情?那我们可以做太多事了,基本上掌握了字符组和量词就可以应付大部分的简单正则了。

    我们使用反向学习法,先看题分析,带着疑问去看api表,可以读懂正则之后再加上练习就等于掌握

    Q1:

    const r = /\d{m,n}/
    

    解析:首先我们看\d,意思代表匹配数字,{m,n}是量词,代表的是匹配次数。那么此题的意思就是匹配m到n个数字

    Q2:

    const r = /[A-Za-z0-9]+/
    

    解析:[A-Za-z0-9]代表匹配英文字母和数字,+代表1次及以上,此题的意思就是:匹配1次及以上的字母或数字

    Q3: 匹配16进制颜色

    const regex = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
    

    解析:16进制可能会是6位#FFFFFF 也可能是3位 #FFF,这边才有纵向匹配,使用量词{6}{3} 加上管道符即可。图片解析如下:

    前端必会-快速掌握正则表达式

    2.3 正则匹配位置

    在ES5中,共有 6 个锚: ^、$、\b、\B、(?=p)、(?!p),常用的有如下2个:

    2.31 ^ 和 $

    • ^(脱字符)匹配开头,在多行匹配中匹配行开头。
    • $(美元符号)匹配结尾,在多行匹配中匹配行结尾。

    做题环节:

    Q1:

    var result = "hello".replace(/^|$/g, '#');
    console.log(result);
    // => "#hello#"
    

    Q2:不匹配任何字段

    const r = /.^/
    

    解析:因为此正则要求只有一个字符,但该字符后面是开头,而这样的字符串是不存在的。

    2.32 \b 和 \B

    \b 是单词边界,具体就是 \w\W 之间的位置,也包括 \w^ 之间的位置,和 \w$ 之间的位置。

    var result = "[JS] Lesson_01.mp4".replace(/\b/g, '#');
    console.log(result);
    // => "[#JS#] #Lesson_01#.#mp4#"
    

    解析:\w 是字符组 [0-9a-zA-Z_] 的简写形式,而 \W 是排除字符组 [^0-9a-zA-Z_] 的简写形式。

    • 第 1 个,两边字符是 "[" 与 "J",是 \W 与 \w 之间的位置
    • 第 2 个,两边字符是 "S" 与 "]",也就是 \w 与 \W 之间的位置
    • 第 3 个,两边字符是空格与 "L",也就是 \W 与 \w 之间的位置。
    • 第 4 个,两边字符是 "1" 与 ".",也就是 \w 与 \W 之间的位置。
    • 第 5 个,两边字符是 "." 与 "m",也就是 \W 与 \w之间的位置。
    • 第 6 个,位于结尾,前面的字符 "4" 是 \w,即 \w 与 $ 之间的位置。

    \b 的概念理解了,\B 的概念也就很好理解了,\B 就是 \b 的反面的意思,

    var result = "[JS] Lesson_01.mp4".replace(/\B/g, '#');
    console.log(result);
    // => "#[J#S]# L#e#s#s#o#n#_#0#1.m#p#4"
    

    2.33 (?=p) 和 (?!p)

    (?=p),其中 p 是一个子模式,即 p 前面的位置,或者说,该位置后面的字符要匹配 p。 比如 (?=l),表示 "l" 字符前面的位置:

    var result = "hello".replace(/(?=l)/g, '#');
    console.log(result);
    // => "he#l#lo"
    

    而 (?!p) 就是 (?=p) 的反面意思:

    var result = "hello".replace(/(?!l)/g, '#');
    console.log(result);
    // => "#h#ell#o#"
    

    做题环节:

    Q3:数字的千分位表示

    var result = "12345678".replace(/(?=(\d{3})+$)/g, ',')
    console.log(result);
    // => "12,345,678"
    

    解析:其中(?=(\d{3}) 代表匹配位置在3位数字的前面+$代表最少出现一次。g全局匹配

    乍一看,我们这个正则是写完了,其实不然,写完正则要多测几组,就会发现问题

    var result = "123456789".replace(/(?=(\d{3})+$)/g, ',')
    console.log(result);
    // => ",123,456,789"
    

    这是因为我们的正则从结尾向前数,一但是 3 的倍数,就把其前面的位置替换成逗号。这个解决方法其实很简单,我们只要不匹配开头不就好了,匹配开头我们知道用^,那不匹配呢?用(?!^) 正则修改如下:

    var regex = /(?!^)(?=(\d{3})+$)/g;
    var result = "12345678".replace(regex, ',')
    console.log(result);
    // => "12,345,678"
    result = "123456789".replace(regex, ',');
    console.log(result);
    // => "123,456,789"
    

    加大难度

    Q4:密码长度 6-12 位,由数字、小写字符和大写字母组成,但必须至少包括 2 种字符。 不考虑“但必须至少包括 2 种字符”这一条件。我们可以容易写出:

    var regex = /^[0-9A-Za-z]{6,12}$/;
    

    如果必须要包含数字呢:

    var regex = /(?=.*[0-9])^[0-9A-Za-z]{6,12}$/;
    

    我们只需明白(?=.*[0-9])^,分开来看就是 (?=.*[0-9])^。表示开头前面还有个位置(当然也是开头,即同一个位置)。(?=.*[0-9]) 表示该位置后面的字符匹配 .*[0-9],即,有任何多个任意字符,后面再跟个数字。就是接下来的字符,必须包含个数字。

    最终答案:

    // 解法1:
    var regex = /((?=.*[0-9])(?=.*[a-z])|(?=.*[0-9])(?=.*[A-Z])|(?=.*[a-z])(?=.*[A-Z]))^[0-9A-Za-z]{6,12}$/;
    // 解法2:
    var regex = /(?!^[0-9]{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)^[0-9A-Za-z]{6,12}$/;
    

    大家可以好好读一下,思考两种解法的意思。

    2.4 分组

    简单点说分组就是括号

    直接做题

    Q1:把 yyyy-mm-dd 格式,替换成 mm/dd/yyyy

    var regex = /(\d{4})-(\d{2})-(\d{2})/;
    var string = "2017-06-12";
    var result = string.replace(regex, "$2/$3/$1");
    console.log(result);
    // => "06/12/2017"
    

    解析:其中 replace 中的,第二个参数里用 $1$2$3 指代相应的分组。

    Q2:一个正则支持匹配如下三种格式:2016-06-12 2016/06/12 2016.06.12

    很容易有如下答案

    var regex = /\d{4}(-|\/|\.)\d{2}(-|\/|\.)\d{2}/;
    var string1 = "2017-06-12";
    var string2 = "2017/06/12";
    var string3 = "2017.06.12";
    var string4 = "2016-06/12";
    console.log( regex.test(string1) ); // true
    console.log( regex.test(string2) ); // true
    console.log( regex.test(string3) ); // true
    console.log( regex.test(string4) ); // true
    

    其中 /. 需要转义。虽然匹配了要求的情况,但也匹配 "2016-06/12" 这样的数据。修改如下:

    var regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/;
    var string1 = "2017-06-12";
    var string2 = "2017/06/12";
    var string3 = "2017.06.12";
    var string4 = "2016-06/12";
    console.log( regex.test(string1) ); // true
    console.log( regex.test(string2) ); // true
    console.log( regex.test(string3) ); // true
    console.log( regex.test(string4) ); // false
    

    可视化形式如下:

    前端必会-快速掌握正则表达式

    注意里面的 \1,表示的引用之前的那个分组 (-|\/|\.)。不管它匹配到什么,\1 都匹配那个同样的具体某个字符。

    括号嵌套 以左括号(开括号)为准

    var regex = /^((\d)(\d(\d)))\1\2\3\4$/;
    var string = "1231231233";
    console.log( regex.test(string) ); // true
    console.log( RegExp.$1 ); // 123
    console.log( RegExp.$2 ); // 1
    console.log( RegExp.$3 ); // 23
    console.log( RegExp.$4 ); // 3
    

    可视化形式如下:

    前端必会-快速掌握正则表达式

    Q3:字符串 trim 方法模拟。 trim 方法是去掉字符串的开头和结尾的空白符

    // 解法1:匹配到开头和结尾的空白符,然后替换成空字符
    function trim(str) {
      return str.replace(/^\s+|\s+$/g, ''); }
    console.log( trim(" foobar ") );
    // => "foobar
    
    // 解法2:匹配整个字符串,然后用引用来提取出相应的数据
    function trim (str) {
      return str.replace(/^\s*(.*?)\s*$/g, "$1"); }
    console.log( trim(" foobar ") );
    // => "foobar"
    

    Q4:将每个单词的首字母转换为大写

    function titleize (str) {
      return str.toLowerCase().replace(/(?:^|\s)\w/g, function (c) {
      return c.toUpperCase();
      }); }
    console.log( titleize('my name is epeli') );
    // => "My Name Is Epeli"
    

    Q5: HTML 转义和反转义

    // 将HTML特殊字符转换成等值的实体
    function escapeHTML (str) {
      var escapeChars = {
      '<' : 'lt',
      '>' : 'gt',
      '"' : 'quot',
      '&' : 'amp',
      '\'' : '#39'
      };
      return str.replace(new RegExp('[' + Object.keys(escapeChars).join('') +']', 'g'),
    function (match) {
      return '&' + escapeChars[match] + ';';
      }); }
    console.log( escapeHTML('<div>Blah blah blah</div>') );
    // => "&lt;div&gt;Blah blah blah&lt;/div&gt";
    
    // 实体字符转换为等值的HTML。
    function unescapeHTML (str) {
      var htmlEntities = {
      nbsp: ' ',
      lt: '<',
      gt: '>',
      quot: '"',
      amp: '&',
      apos: '\''
      };
      return str.replace(/\&([^;]+);/g, function (match, key) {
      if (key in htmlEntities) {
      return htmlEntities[key];
      }
      return match;
      }); }
    console.log( unescapeHTML('&lt;div&gt;Blah blah blah&lt;/div&gt;') );
    // => "<div>Blah blah blah</div>"
    

    3. 结尾

    其实到这里,基本上常用的正则api都已经出现了,剩下的就是活学活用了,大家可以在工作中某些以前用js的api的地方现在换成正则,即装b,又可以更好的掌握正则。

    由于本人技术有限,如文内有错误,还望指出,感谢!

    参考文章:《JavaScript正则表达式迷你书》


    起源地下载网 » 前端必会-快速掌握正则表达式

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元