美文网首页
正则表达式基础及实践

正则表达式基础及实践

作者: 流云012 | 来源:发表于2018-08-03 14:38 被阅读0次

    基本简介

    正则表达式(Regular Expression): 通过由普通字符和特殊字符组成的文字模板完成对字符串的校验,检索,替换,作用:

    1. 给定的字符串是否符合正则表达式的过滤逻辑(匹配)
    2. 可以通过正则表达式,从字符串中获取我们想要的特定部分(提取)
    3. 强大的字符串替换能力(替换)

    一、创建一个正则表达式

    1. 调用RegExp对象的构造函数

       let regExp = new RegExp('ab+c');
       let regExp = new RegExp('^[a-z]+[0-9]$', 'gi');
      

      第一个参数是匹配模式,第二个参数是可选参数(g,i,m),分别用于指定全局匹配、区分大小写的匹配和多行匹配。这种方式会在正则表达式运行时编译,多用于传参或者从另一来源获取。

    2. 使用正则表达式字面值,将匹配模式封闭在两个斜杠中

       const regExp = /ab+c/;
       const regExp = /^[a-z]+[0-9]$/gi;
      

      当表达式被赋值时,字面量形式提供正则表达式的编译,当正则表达式保持为常量时一般使用字面量方式。

    二、组成部分

    正则表达式的文字模板是有很多不同类型的字符组成的,包括:修饰符,位置字符、元字符,转义字符,限定符,或结构,括号分组

    • 修饰符

      字符 含义
      g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)
      i 表示忽略大小写匹配
      m 执行多行匹配

    g全局匹配类似搜索,因此不能使用 /^...$/,那样只会最多匹配一次

    • 位置字符

      字符 含义
      ^ 表示字符串的开始位置
      $ 表示字符串的结束位置
      // test必须出现在开始位置
      /^test/.test('test123') // true
      
      // test必须出现在结束位置
      /test$/.test('new test') // true
      
      // 从开始位置到结束位置只有test
      /^test$/.test('test') // true
      /^test$/.test('test test') // false
      
    • 元字符

      字符 含义 字符 含义
      . 匹配除了换行符(n)以外的所有字符
      \w 匹配字母,数字,或者汉字 \W 匹配除了字母,数字,汉字以外的其他字符
      \d 匹配数字 \D 匹配除了数字以外的其他字符
      \s 匹配任意的空白符(f,n,r,t,v) \S 匹配空白符以外的任意字符
      \b 匹配单词的开始或者结束 \B 匹配单词的非开始或者结束
      \n 查找换行符 \r 查找回车符
      ^ 匹配行首 $ 匹配行尾
    • 转义字符

      ? * + | { [ ( ) ] } ^ $ . # 和 空白 以及 部分元字符 这些字符都是需要转义的。例如:需匹配 { 。

      \{  \d   \[
      
    • 限定符 -- 量词

      字符 含义 字符 含义
      * 匹配零次至多次 + 匹配一次至多次
      ? 匹配零次或一次 {n,} 至少匹配 n 次,n 为正整数
      {n} 匹配 n 次, n 为正整数 {{m,n}} 至少匹配 m 次,之多匹配 n 次,m,n 为正整数
    • **字符组[] 和 结构 | **

      中括号字符组用来匹配括号内的字符之一

       'fasfagxfasdfyfasfz'.split(/[xyz]/) //["fasfag", "fasdf", "fasf", ""]
       /c|d/.test('af') // false
       /c|d/.test('ad') // true
      

      还有一种排除性字符组

       'xaxbycz'.split(/[^xyz]/) //["x", "x", "y", "z"]
      
    • 括号分组

      (cd){1,} 可以匹配 cdcd.. 等,其中 cd 便是一个分组。

    • 贪婪模式 和 非贪婪模式

      默认情况下,所有的限定词都是贪婪模式,表示尽可能多的去捕获字符,而在限定符后增加“?”,则是非贪婪模式,表示尽可能少的去捕获字符。

        'ccccccd'.match(/c+/) //["ccccc"], 贪婪模式, 捕获所有
      'ccccccd'.match(/c+?/) //["c"], 非贪婪模式, 只捕获到第一个
      
    • 捕获分组 1~9属性

      RegExp.$1...$9 属性值为 String类型,用于返回正则表达式模式中某个子表达式匹配的文本,正则表达式中每个小括号内的部分表达式就是一个子表达式。

       var str = 'X98Y87Z65';
       var reg = /^X(\d+)Y(\d+)Z(\d+)$/;  // 三个数字部分加了小括号,表示子表达式
       reg.test(str);  // 此处使用exec()等其他正则表达式的匹配方法也可以
       console.log(RegExp.$1);  // 98
       console.log(RegExp.$2);  // 87
       console.log(RegExp.$3);  // 65
       
       str = '<a href="http://www.365mini.com/" title="首页" target="_blank">CodePlayer</a>';
       reg = /<a\s[^>]*href="([^">]+)"[^>]*>/;   // 提取URL
       reg.exec(str);
       console.log(RegExp.$1);  // http://www.365mini.com/
       
       var str = '123-mm';
       var strReg = str.replace(/(\d+)-([A-Za-z]+)/g,'$2');
       console.log(strReg)  //mm  上面那段$2这个就是表示正则第二组个匹配到的内容
      

    使用方法

    一、RegExp基本方法(prototype)

    • test: 检索字符串中的指定子字符串是否存在,返回布尔值 true 或 false

       /^\d[a-zA-Z]{3}$/.test('1aac')   // true
      
    • exec: 查找满足条件的匹配,返回一个数组(未匹配到返回null)

       /^\d[a-zA-Z]{3}$/.exec('1aac')   // ['1aac']
      

    二、字符串(String)方法

    • search: 返回子字符串的开始位置索引,匹配没有则返回 -1

       'a12b2334c34'.search(/\d{4}/)    // 4 
       'a12b23a34c34'.search(/\d{4}/)   // -1 
      
    • match: 返回一个数组,成员是所有匹配的子字符串,匹配没有则返回 null

       'a12b2334c34'.match(/\d{4}/)     // ["2334"]
       'a12b2334c3412'.match(/\d{4}/g)  // ["2334", "3412"]
       'a12b23a34c34'.match(/\d{4}/)    // null
      
    • replace: 按照给定的正则表达式进行替换,返回替换后的字符串。

       'a12b2334c34'.replace(/\d{4}/, 'cccc') // "a12bccccc34"
       'a12b2334a3412'.replace(/\d{4}/g, 'cccc') // "a12bccccacccc"
      
    • split: 按照给定规则进行字符串分割,返回一个数组,包含分割后的各个成员。

       'a12b2334c34'.split(/\d{4}/)  // ["a12b", "c34"]
       'a12 b2334 c34'.split(/ /)    // ["a12", "b2334", "c34"]
       'a12,b2334,c34'.split(',')    // ["a12", "b2334", "c34"]
      

    备注: test 和 search 方法较快,常用于判断匹配条件是否满足; exec 和 match 方法比较慢,但可得到更多信息。

    项目中实践

    • 手机号验证(常见号段)

      let phoneReg = /^[1][3-9][0-9]{9}$/
      phoneReg.test('18766567132')
      
    • 短信验证码(4位 或 6位)

      let codeReg = /^[0-9]{4}$/
      codeReg.test('8190')
      
    • 删除字符串空格

      let str = '  字符串   测试  功能    '
      // 去掉前面空格
      str.replace(/^\s*/g, '')
      
      // 去掉后面空格
      str.replace(/\s*$/g, '')
      
      // 去掉前后空格
      str.replace(/(^\s*)|(\s*$)/g, '')
      
      // 去掉所有空格
      str.replace(/\s+/g, '')
      
      // 只去掉中间空格?
      
    • 获取url里面的 hash name值

      location.href = 'https://activity.xueersi.com/topic/growth/inviteNew/#/register?s=20001&g=0&u=15904340'
      let _hashName = /#\/(.*)?\?*/gi.exec(window.location.href)[1] || ''
      let _hashName = window.location.hash.split('?')[0].split('#/')[1] || ''
      
    • 身份证校验(15位 或者 18位)

      // 最简验证
      const cardReg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
      // 严格验证
      const cardReg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$/
      
    • 匹配文件内所有的 console.log() 或者 注释内容( // 和 /* */)

      // 匹配 console.log
      const logReg = /console.log\(.*\)/
      
      // 匹配 // 注释内容
      const regExp = /\/\/\s*.*/
      
      // 匹配 /* 注释内容 */  
      const regExp = /\/\*\s*.*\*\//
      
    • 获取 background-image 背景图里面的 url 地址:

      $('.img').css('background-image').replace(/url\(([^\)]+)\).*/,'$1');
      
    • 获取 url 上的参数,返回对象格式

      // 获取 url 参数,返回参数集合对象
      function getUrlParmas(url) {
          var vars = {}
          url.replace(/[?&]+([^=&]+)=([^&#]*)/gi, function(m, key, value) {
              vars[key] = value
          })
          return vars
      }
      // 测试
      location.href.replace(/[?&]+([^=&]+)=([^&#]*)/gi, function(m, key, value) {
          console.log(m , key, value)
      })
      

    常见正则表达式汇总

    • Email 地址:

       var reg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
      
    • URL验证:

      var reg = /[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$/
      
    • 中文验证:

      var reg = /[\u4e00-\u9fa5]/gm;
      
    • 严格的手机号验证

      var reg = /^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i;
      
    • 去掉前后空格

       // 去掉前后空格
      trim: function(str) {
          var reg = /^\s+|\s+$/g;
          return str.replace(reg, '');
      },
      
    • 身份证号部分:

       var reg = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;
      
    • 检验字符的表达式

    // 1. 汉字:
    ^[\u4e00-\u9fa5]{0,}$
    
    // 2. 英文和数字:
    ^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
    
    // 3. 长度为3-20的所有字符:
    ^.{3,20}$
    
    // 4. 由26个英文字母组成的字符串:
    ^[A-Za-z]+$
    
    // 5. 由26个大写英文字母组成的字符串:
    ^[A-Z]+$
    
    // 6. 由26个小写英文字母组成的字符串:
    ^[a-z]+$
    
    // 7. 由数字和26个英文字母组成的字符串:
    ^[A-Za-z0-9]+$
    
    // 8. 由数字、26个英文字母或者下划线组成的字符串:
    ^\w+$ 或 ^\w{3,20}$
    
    // 9. 中文、英文、数字包括下划线:
    ^[\u4E00-\u9FA5A-Za-z0-9_]+$
    
    // 10. 可以输入含有^%&',;=?$\"等字符:
    [^%&',;=?$\x22]+
    
    // 11. 禁止输入含有~的字符:
    [^~\x22]+
    
    • 特殊需求表达式
    // 1. Email地址:
    ^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
    
    // 域名:
    [a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
    
    // InternetURL:
    [a-zA-z]+: // [^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
    
    // 2. 手机号码:
    ^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
    
    // 3. 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):
    ^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
    
    // 4. 国内电话号码(0511-4405222、021-87888822):
    \d{3}-\d{8}|\d{4}-\d{7}
    
    // 5. 身份证号(15位、18位数字):
    ^\d{15}|\d{18}$
    
    // 6. 短身份证号码(数字、字母x结尾):
    ^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
    
    // 7. 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):
    ^[a-zA-Z][a-zA-Z0-9_]{4,15}$
    
    // 8. 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):
    ^[a-zA-Z]\w{5,17}$
    
    // 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):
    ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
    
    // 9. 日期格式:
    ^\d{4}-\d{1,2}-\d{1,2}
    
    // 10. 一年的12个月(01~09和1~12):
    ^(0?[1-9]|1[0-2])$
    
    // 11. 一个月的31天(01~09和1~31):
    ^((0?[1-9])|((1|2)[0-9])|30|31)$
    
    // xml文件:
    ^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
    
    // 12. 中文字符的正则表达式:
    [\u4e00-\u9fa5]
    
    // 13. 双字节字符: (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
    [^\x00-\xff]   
    
    // 14. 空白行的正则表达式:(可以用来删除空白行)
    \n\s*\r   
    
    // 15. HTML标记的正则表达式:(网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
    <(\S*?)[^>]*>.*?</\1>|<.*? />   
    
    // 16. 首尾空白字符的正则表达式:(可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
    ^\s*|\s*$或(^\s*)|(\s*$)    
    
    // 17. 腾讯QQ号: (腾讯QQ号从10000开始)
    [1-9][0-9]{4,}   
    
    // 18. 中国邮政编码:   (中国邮政编码为6位数字)
    [1-9]\d{5}(?!\d) 
    
    // 19. IP地址: (提取IP地址时有用)
    \d+\.\d+\.\d+\.\d+   
    
    // 20. IP地址:
    ((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
    

    相关文章

      网友评论

          本文标题:正则表达式基础及实践

          本文链接:https://www.haomeiwen.com/subject/hqgyvftx.html