美文网首页
正则表达式

正则表达式

作者: fanstastic | 来源:发表于2019-11-20 23:06 被阅读0次

    . 匹配任意字符
    正则表示的是一个组合,配合任意一个非断行字符
    .转义
    \w 表示文字和大小写字母_
    \W 表示\w的反向匹配字符
    \d 表示匹配阿拉伯数字
    \D 匹配非数字
    \s 空格,tab,换行
    \S 非
    [] 匹配[]中的任意一个值,也可以是范围,如果想匹配中文,可以使用中文的unicode
    \u4e00-\u9fa5,\u表示是万国码unicode,4e00和9fa5表示中文文字之间的范围,给定的是一个unicode范围,[ab]a或者b
    +表示前面的字符可以出现一次或者多次
    [ab][cd]+表示方括号的唯一值可以出现一次或多次,a或者b表示唯一的值
    .在括号中要转义

    • 表示0次或者多次
      ?表示0次或者1次
      {} 表示匹配字符的重新字数
      分组匹配
      使用()进行分组 1 表示第一组2 表示第二组
      贪婪,尽可能的多
      a.b aabaaab => aabaaab 默认是贪婪模式,.会尽可能多的去匹配组,尽可能多的去匹配。
      a.
      ?b aabaaaab => aab 尽可能少的去匹配,尽可能少的去匹配
      在匹配次数后面加问号,表示懒惰 *?重复任意次,尽可能少的重复。+?重复一次或更多次,尽可能少的重复。??重复0或者1次,但尽可能少的重复。
      位置符
      ^ $ ?=x \b \B
      12332132 => 12.332.132

    首先我们需要在两个位置中插入两个点,所以需要找出这两个位置,位置都出现在了三个数字的前面,并且还需要从后往前匹配,所以需要匹配行尾部
    /(?=\d{3})+/g \B就是\b的反面,\b是\w与\W之间的位置,具体来说就是\w \w \W \W \W ^之间的位置,位置和元素之间也可以匹配位置。
    (?=p) 其中p是一个子模式,即p前面的位置
    (?!p) 不是p前面的位置

    位置的特性

    对于位置的理解,我们可以理解成空字符

    • 不匹配任何东西的字符
      /.^/ 开头的位置前面是没有字符的
    1. 弄出最后一个分号12131232
      (?=\d{3}) 匹配的是\d{3}前面的位置,\d{3}则表示正则的最后三位
      弄出所有的逗号
      (?=(\d{3})+) , 因为逗号出现的位置,要求后面3,6,9,12数字的前面出现,一旦出现3的倍数就进行替换 字符串首位不能出现,(?!^)(?=(\d{3})+)
      (?!\b)(?=(\d{3})\b)
      格式化
      把字符串1888 => 1,888.00 function format(num) { return num.toFixed(2).replace(/\B(?=(\d{3})+\b)/g, ',').replace(/^/, ' ');
      }
      验证密码的问题
      是否包含某种字符
      判断是否包含数字,将字符串中的所有位置找出来(?=.\d)判断这个位置的后一个字符是否是数字,如果存在这样的匹配,那么说明字符串中有数字
      位置匹配的字符串往往放在字符串的最前面
      (?=.
      \d)(?=.[a-z])
      (?=.
      [0-9])^,表示开头前面还有个位置

    2. 正则表达式括号的作用
      括号提供了分组,便于我们引用它。
      引用包括两种情形,一种在js里引用,另一种在正则里引用

    分组与分支结构

    • 分组
      比如(ab)+()括号提供分组,使得+量词作用于()内部的整体,即提供子表达式。
      |分支往往要搭配分组括号使用

    • 分组引用
      正则引擎在匹配的过程中,会给每一个分组开辟一个空间,用来存储每个分组的数据。
      match返回一个数组,第一个元素是整体匹配结果,然后是各个分组匹配的内容,然后是匹配下标,是否有修饰符g,match返回的结果也不一样

    同时也可以通过正则构造函数的全局属性来获取分组
    只要执行正则操作即可,比如test,exec,match
    RegExp.1 RegExp.2

    let regex = /(\d{4})-(\d{2})-(\d{2})/
    let string = '2019-08-09'
    string.replace(regex, '$1/$2/$3')
    == 
    string.replace(regex, () => RegExp.$1 + '/' + RegExp.$2 + '/' + RegExp.$3)
    string.replace(regex, (match, year, month, day) => )
    正则被执行后会保存分组,分组通过全局的正则函数RegExp访问,
    replace的第二个参数可以是回调函数,回调函数的第一个参数是正则匹配到的值,后面的参数是分组
    
    • 反向引用
      除了使用相应的api引用分组,也可以在正则本身里引用分组。但是只能引用之前出现的分组。既反向引用。
      /\d{4}(-|/|.)\d{2}(-|/|.)\d{2}/
      /\d{4}(-|/|.)\d{2}\1\d{2}/
      \1 \2 在正则里分别代表第一个和第二个分组
      分组会将匹配到的内容提取出来,保存到内存中

    1.如果引用了不存在的分组,就会反向匹配引用字符本身

    1. 如果分组后面有量词,那么最终捕获到的数据是最后一次的匹配
      之前文中出现的括号,都会捕获他们匹配到的数据,以便后续引用,因此也称捕获行分组,如果只是使用括号里最原始的功能,(?:xxx)
      字符串trim方法模拟
      /^\s|\s$/g 去掉首尾空格
      将每个单词的首字母转换为大写
      string.replace(/(\s|^)\w/g, (value) => value.toUpperCase())
      驼峰转换
      string.replace(/-(\w)/g, (value, group1) => group1.toupperCase())
      html转义
    const escapeHTML = (str) => {
          const escapeChars = {
            '<': 'a'
          }
          return str.replace(new RegExp('[' + Object.keys(escapeChars).join('') + ']')
            (value) => escapeChars[value]
          )
    }
    

    /<([a-z]+)>.+</\1>/g

    正则表达式的回溯法原理

    内容:

    1. 没有回溯的匹配
    2. 有回溯的匹配
    3. 常见的回溯形式

    回溯法也称试探法,从问题的某一种状态出发,探索从这种状态出发所能达到的所有状态,当一条路走到尽头的时候,再后退一步或者若干步,从另一种可能的状态出发,继续搜索,直到所有的可能都被探索过。这种不断前进不断回溯的方法就叫回溯法。本质上就是深度优先搜索算法,其中退到之前某一步的过程,我们称为回溯

    • 贪婪量词
      比如b{1, 3}因为其是贪婪的,尝试可能的顺序是从多往少的方向去尝试,首先尝试bbb,然后看整个正则能否匹配,不能匹配时,吐出一个b,再继续尝试,往复循环,直到满足要求。

    • 惰性量词
      惰性量词就是在贪婪量词后面加一个?

    • 分支结构
      分支结构也是惰性的,比如/can|candy/,得到的结果是can,因为分支会一个一个尝试,如果满足了就不会在尝试后面的分支。
      非捕获分组?
      当尝试匹配时,需要确定从哪一个位置开始匹配,一般都是从字符串的开头
      当使用test和exec方法,且正则有g时,起始位置是从正则实例的lastIndex位置开始。

    优化正则性能

    1. 通过使用非捕获型分组提升性能
    2. 独立出确定字符
    3. 提取分支公共部分
    4. 减少分支的数量,缩小它们的范围

    正则表达式的四种操作

    1. 验证
      match返回结果的格式问题,分为是否有g两种情况
      没有g => [ 匹配的值,分组匹配的值,匹配开始的位置,需要匹配的字符串 ]
      有g => 返回的是所有匹配的内容
      当没有匹配时,不管有无g,都返回null

    相关文章

      网友评论

          本文标题:正则表达式

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