美文网首页
正则表达式常用学习

正则表达式常用学习

作者: storyWrite | 来源:发表于2022-01-02 20:03 被阅读0次

0.简介

regular expression,规则表达式,是一种用来处理字符串的规则,巧妙的正则表达式可以节省很多判断代码.

1.组成

  • 元字符
    • 特殊元字符

\ 转义字符 => 普通字符 <=> 特殊字符
. 点 => 代表除了\n 以外的任意字符(字符字符字符)
^ => 以哪个元字符开始
$ => 以哪个元字符作为结束
\n 任意一个换行符
\d 0-9之间的一个数字
\D 除了0-9之间的任意字符
\w 数字字母下划线中的任意一个字符
\W
\s 一个空白字符 空格 制表符 换页符等
\t 一个制表符 4个空格
\b 单词边界
x | y 或者
[xyz] => x | y | z
[^xy] => 除了 x | y 的任意字符
[a-z]
[^a-z]
(正则中的分组符号)
(?:) => 只匹配不捕获
(?=) => 正向预查
(?!) => 负向预查

  • 量词元字符

* => 0-多次
+ => 1-多次
? => 0 - 1次
{n} => 出现n次
{n,m} => 出现n-m次

  • 普通元字符

/abc/ 匹配abc

  • 修饰符
  1. i ignoreCase
    忽略单词大小写
  2. m multiLine
    进行多行匹配
  3. g global
    全局匹配

2.贪婪性

    let str = 'ab2020nb',
    // 贪婪性:默认情况下,捕获的时候,按照当前正则匹配的最长结果来获取
    reg = /\d+?/g
    console.log(str.match(reg))  
    // 在量词后面设置? 取消捕获时候的贪婪性 按照正则匹配的最短结果来获取
    
    /*
      * 问号的作用
      * 问号左边是非量词元字符:则此时问号本身代表两次元字符出现0-1次
      * 问号左边是量词元字符:取消捕获时候的贪婪性  /\d+?/g
      * (?:) 只匹配不捕获
      * (?=) 正向预查
      * (!=) 负向预查
    */

3.懒惰型

   /*
       * 基于exec的捕获
       * 捕获到的结果是一个数组或者null
       * 第一项:本次捕获到的内容
       * 其余项:对应小分组本次单独捕获的内容
       * 当前捕获内容在字符串中的索引
       * input:原始字符串
       * 每执行一次exec只能捕获到一个符合正则规则的字符串,默认情况下执行多次也只能匹配第一次捕获的结果  => 正则捕获的懒惰型
       * 懒惰产生的原因:每一次匹配的lastIndex值不变 只能通过全局修饰符才能改变这一特性
       * lastIndex : 当前正则匹配下一次匹配的起始索引位置
       *
       * 设置全局匹配符g之后第一次匹配完成之后会自动修改lastIndex的值
       * 此时可以进行循环多次进行匹配
       *
       */
      let str = 'nb13奥利给6666aaaa',
        reg = /\d+/g

4.举例几个简单正则表达式

  • 1).验证手机号
     //  \^abc0$\  只能是abc0

      // 验证手机号
      let tel = /^1\d{10}$/ //1后面十位数字

      let reg1 = /^2.3$/ //=> 只能匹配2中间一个除了换行之外的任意字符 3
      console.log(reg1.test('2.3'))
      console.log(reg1.test('253'))
      console.log(reg1.test('2@3'))
      let reg2 = /^2\.3$/ //=> 只能是2.3
      console.log(reg2.test('2.3'))
      let reg3 = /^\\d$/ // => 匹配   \d  特殊转换为普通
      console.log(reg3.test('\\d'))

      // 直接使用 /^18|69$/  存在很乱的优先级问题
      // /^(18|69)$/  这样不存在优先级混乱问题

      // [] 中括号出现的字符一般都是代表本身的含义 且不包含多位数 只能是一位数
      // /^[@+]/$  出现@ 或者+ 中的一个
      //  /^[\d]$/  \d在中括号中还是0-9数字
      //  /[10-29]/  1 0 - 2 9
  • 2).验证是否为有效数值
     // 验证是否为有效数值
      // 规则分析: 可能出现正负号 只出现一位  [+-]?
      //        一位0-9 多位不能0开头 (\d | [1-9]\d+)
      //        小数部分可能有可能没有 有小数点后面必须有数字 (\.\d+)?
      // 重点重点重点  正则中不能随意添加空格,空格会被识别当做判别中的一位
      let num = /^[+-]?(\d|([1-9]\d+))(\.\d+)$/
      console.log(num.test('+0.1'))
// 更简单
isNaA(parseFloat(num)) === true 
  • 3)验证真实姓名
      /*
       *验证真实姓名
       * 汉字范围 /^[\u4E00-\u9FA5]$/
       * 名字长度2-10
       * 可能有译名  .汉字
       *
       * /^[\u4E00-\u9FA5]{2,10}(·[\u4E00-\u9FA5]{2,10}){0,2}$/
       *
       */
      let reg = /(.)?/
      reg.test('.')
    1. 验证邮箱
      /*
       *验证邮箱
       *  \w+((-\w+)|(\.\w+))*
       * 开头是字母数字下划线(1-多位)
       * 还可以输 -数字字母下划线 或者.数字字母下划线 *
       * 邮箱的名字由数字字母下划线- . 几部分组成但是.-不能连续出现或者作为开头
       *
       * @[A-Za-z0-9]+
       * @后面数字字母1-多位
       *
       * ((\.|-)[A-Za-z0-9]+)*
       * 对@后面名字的补充
       * 多域名  .com.cn
       * 企业邮箱 zdz@jiazu-qiye.com
       *
       * \.[A-Za-z0-9]+
       * 匹配最后的常规    .com  域名
       */

      let email =
        /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-za-z0-9]+)*\.[A-Za-z0-9]+$/
    1. 身份证验证
  /*
      *身份证
      *规则:
            1.一共18位
            2.最后一位可能是X  代表10
            前六位:省市县
            最后四位:
              最后一位X或者数字
              倒数第二位: 偶数女 奇数 男
              其余两位经过算法算出

              小括号还具有:分组捕获功能,不仅可以把大正则匹配的信息捕获,还可以单独捕获到每个小组的内容
      *
    */
      let id = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/
      console.log(id.exec('37152219900101823X'))

5.以前学习的记录

  let time = '2020-11-6'  // => 2020年11月16日
    let reg = /^(\d{4})-(\d{1,2})-(\d{1,2})/g
    time2 = time.replace(reg,'$1年$2月$3日')
    console.log(time2)

    // 思路:拿reg和time匹配捕获,匹配几次就会把传递的函数执行几次
    //      不仅把方法执行而且replace还会把实参信息传递给函数
    time1 = time.replace(reg,(...arg) => {
      console.log(arg)
      // 参数中第一项为捕获到的完整字符串,其后为每次捕获到的小分组
      // 最后一项为匹配字符串 倒数第二项为第一次匹配的索引
      let [,$1,$2,$3] = arg
      function padZero(str) {
        return ('00' + str).slice(str.length)
      }
      $2 = padZero($3)
      $3 = padZero($2)
      return $1 + '年' + $2 + '月' + $3 
      + '日'
    })
    console.log(time1)

   // 首字母大写  replace不改变原字符串

    let reg1 = /\b([a-zA-Z])[a-zA-Z]+\b/g
    let str1 = 'good good study day day up!'
    // 函数执行6次
    str1 = str1.replace(reg1,(...arg) => {
      // 参数的第一项是匹配的完整分组 good 第二项是匹配到的小分组 g
      console.log(arg)
      let [content,$1] = arg
      $1 = $1.toUpperCase()
      content = content.slice(1)
      return $1 + content
    })
    console.log(str1)
  • 字母出现最大次数
 /*
      * 如何验证一个字符串中那个字符串出现的次数
      *
      *
    */

    let str = 'aaabbbbbbbbccccbcccccd'
    // 去重
    function statastic(str) {
      let obj = {},
        max = 1,
        res = []
        ;[].forEach.call(str, char => {
          if (typeof obj[char] !== 'undefined') {
            obj[char]++
            return
          }
          obj[char] = 1
        })
      for (let key in obj) {
        let item = obj[key]
        item > max ? max = item : null
      }
      for (let key in obj) {
        if (obj[key] === max) {
          res.push(key)
        }
      }
      // 此时res被转换为字符串
      return `maxItem:${res}\nvalue:${max}`
    }
    console.log(statastic(str))


    // 排序
    function statastic1(str) {
      // 将字符串转化为数组排序再转化为字符串
      str = str.split('').sort((a, b) => a.localeCompare(b)).join('')
      // 匹配重复字母
      let reg = /([a-zA-Z])\1+/g
      // 捕获
      let arr = str.match(reg)
      // 把捕获的结果数组根据长度排序 得到一个降序排列的数组里面包含结果数组字符串
      // ["bbbbbbbb", "cccccccc", "aaa"]
      arr.sort((a, b) => b.length - a.length)
      console.log(arr)
      let max = arr[0].length,
        res = [arr[0].substr(0, 1)]
      // 对于可能出现相同次数的字母进行查询
      for (let i = 1; i < arr.length; i++) {
        let item = arr[i]
        if (item.length < max) {
          break
        }
        res.push(item.substr(0, 1))
      }
      return `maxItem:${res}\nvalue:${max}`
    }
    console.log(statastic1(str))

    function statastic3(str) {
      // 字母排序
      str = str.split('').sort((a, b) => a.localeCompare(b)).join('')
      let max = 0,
        res = [],
        flag = false;
        console.log(str)
      for (let i = str.length; i > 0; i--) {
        // 查找出现次数最多的  从最大次数(字符串长度)开始检测
        let reg = new RegExp('([a-zA-Z])\\1{' + (i - 1) + '}', 'g')
        str.replace(reg, (content, $1) => {
          res.push($1)
          max = i 
          flag = true
          // break //不能放在这里 只能放在循环中
        })
        if (flag) {
          break
        }
      }
      return `maxItem:${res}\nvalue:${max}`
    }
    console.log(statastic3(str))
  • 时间字符串格式化
   /*
      * 服务器获取时间字符串格式
      * 2020-11-17 09:00:00
      * 2020/11/17 09:00:00
      * 想要转化为的格式
      * 2020年08月13日
      * 08月13日 09时00分
    */

    function formatTime1(template) {
      // 1.获取字符串中年月日时间
      let timeArr = this.match(/\d+/g)
      template = template || "{0}年{1}月{2}日{3}时{4}分{5}秒"
      template = template.replace(/\{(\d+)\}/g, (content, $1) => {
        let time = timeArr[$1] || '00'
        // 补0
        function padZero(str) {
          return ('00' + str).substr(str.length)
        }
        time = padZero(time)
        return time
      })
      return template
    }
    // 简化代码
    function formatTime(template = "{0}年{1}月{2}日{3}时{4}分{5}秒") {
      let timeArr = this.match(/\d+/g)
      // 直接解构赋值
      return template.replace(/\{(\d+)\}/g, (...[,$1]) => {
        let time = timeArr[$1] || '00'
        return time.length < 2 ? '0' + time : time 
      })
    }

    // 循环扩展原型方法
    ['formatTime'].forEach(item => {
      String.prototype[item] = eval(item)
    })
    let time = '2020-11-17 09:0:00'
    console.log(time.formatTime())
    console.log(time.formatTime('{3}时{4}分{5}秒'))
  • 简单url拆分
    function queryParams(url) {
      let obj = {}
      let reg = /([^?=&#]+)=([^?=&#]+)/g
      url.replace(reg, (...[, $1, $2]) => obj[$1] = $2)
      url.replace(/#([^$=?]+)/, (...[, $1]) => obj.hash = $1)
      return obj
    }
    console.log(queryParams('www.baidu.com?123=456&id=888#box'))
  • 千分符
function millionmeter(num) {
      num += ''
      num = num.split('').reverse().join('')
      for (let i = 3; i < num.length; i += 4) {
        let preV = num.substring(0, i),
          next = num.substring(i)
        num = preV + ',' + next
      }
      return num.split('').reverse().join('')
    }
    let num = 1151781932
    console.log(millionmeter(num))


    function millionmeter1(num) {
      num += ''
      num = num.split('').reverse()
      for (let i = 3; i < num.length; i += 4) {
        num.splice(i,0,',')
      }
      // reverse 不对原数组产生影响
      return num.reverse().join('')
    }

    console.log(millionmeter1(num))

    // 思想:从结尾开始进行前项预查 每三个数字一组,当数字不是三个就进行前一个匹配条件 捕获并且添加逗号 之后剩余所有分组都符合三个一组条件
    function millionmeter2(num) {
      num += ''
      let reg = /\d{1,3}(?=(\d{3})+$)/g
      return num = num.replace(reg,content => content + ',')
      
    }
    console.log(millionmeter2(num))

相关文章

  • 正则表达式与方法

    正则表达式---常用符号 正则表达式--常用函数 正则表达式--常用技巧 代码: 正则表达式的应用举例 1、使用f...

  • 常用正则表达式记录

    正则表达式,如果不常用,经常用一次就忘掉了,需要再次学习,记录一些常用的正则表达式,以便使用时方便查看。正则只适合...

  • 常用正则表达式

    以下是常用的代码收集,学习用。转自豪情博客园 常用的js正则表达式

  • 正则表达式浅略学习

    在javascript编程中,会时常用到正则表达式。因此,决定对正则表达式进行学习。 学习的目的主要是能够在编程中...

  • 总结js常用函数和常用技巧

    学习过程中总结的干货,包括常用函数、常用js技巧、常用正则表达式等。 Ajax封装 使用方法: 后台响应Ajax ...

  • 正则表达式

    正则表达式 正则表达式就是记录文本规则的代码 正则表达式常用的元字符 正则表达式常用的限定符 正则表达式举例:这里...

  • 常用正则表达式符号

    在进行复杂的字符串匹配时,正则表达式往往是最常用的手段,最近在学习爬虫,所以将一些常用的正则表达式表示方式整理了下...

  • Python---正则表达式

    常用正则表达式

  • iOS常用正则表达式(电话、QQ、邮箱等)

    常用正则表达式

  • 正则表达式

    常用正则表达式

网友评论

      本文标题:正则表达式常用学习

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