美文网首页
一文带你学习正则表达式

一文带你学习正则表达式

作者: 拐服第一大码猴 | 来源:发表于2022-01-21 14:40 被阅读0次

    一文带你学习正则表达式

    正则表达式,对于前端而言是不可或缺的技能。表单验证、查找字符串、字符串格式化等等一系列常规操作都需要使用到正则。
    通过单个字符串来描述、匹配满足条件的规则字符串,它是繁琐的,同时也很强大,接下来一文带你了解什么是正则表达式。

    语法

    例如匹配一个千分位格式

        let str = '12,545,545'
        let reg =  /^(\d{1,3},)+(\d{3})$/
        console.log(reg.test(str)) // true
    

    一般的正则表达式都是由两条/前后封闭形成,在上述正则表达式中,以^表示规则的开始,从左到右依次组
    合,\d表示0-9的任意数字,{1,3}表示前面的任意数字至少有1个,至多为3个,","紧跟在后面,表面1-3个任意数字后必须跟
    一个",",将"\d{1,3},"用()包起来表示一个表达式,()外的+表示()中的内容至少要有一个或多个,第二个括号里表示固定的
    任意三个数字,最后由$表示规则的结束。

    前端一般使用正则对象的test方法进行校验(上方例子)

    前端一般使用字符串的replace方法进行格式化字符串以及使用match方法匹配满足正则的字符串:

        // 格式化千分位(replace方法)
        let str = `123145641221`
        let newStr = str.replace(/\d{1,3}(?=(\d{3})+$)/g, (s) => `${s},`)
        console.log(newStr) // '123,145,641,221'
        
        // 查找满足条件的子字符串(match方法)
        let str = 'uzi yyds dddd'
        let reg = /\bd\w+/
        let reg1 = /d\w+/
        str.match(reg) // ['dddd', index: 9, input: 'uzi yyds dddd', groups: undefined]
        str.match(reg1) // ['ds', index: 6, input: 'uzi yyds dddd', groups: undefined]
    
        格式化千分位方法中,我们先匹配千分位的开头,因为千分位的开头数字的位数是不确定的,所以用\d{1,3}来匹配
    ,而大()中的?=则表示的是寻找小()中三个任意数字的前一个表达式的内容,通俗的表达就是要匹配任意1-3个数字
    后必须要有3个任意数字,然后g修饰符则表示匹配整个字符串的内容。
        在查找子字符串方法中,为什么我们的reg1到的是ds,而不是dddd。因为在d前面加了\b定位符,表示d前边必须
    没有元素,或者为空格。若\b在d的后面,则表示d的后面必须没有元素或为空格。
    

    修饰符

    修饰符 含义 说明
    i ignore - 不区分大小写 将匹配设置为不区分大小写,搜索时不区分大小写: A 和 a 没有区别。
    g global - 全局匹配 查找所有的匹配项。
    m multi line - 多行匹配 使^ 也匹配 '\n' 或 '\r' 之后的位置,$ 也匹配 '\n' 或 '\r' 之前的位置。
    s 特殊字符圆点 . 中包含换行符 \n 默认情况下的圆点 . 是 匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后, . 中包含换行符 \n。

    元字符

    字符类型 描述
    \ 转义字符,使*,+,?等特殊字符失去特殊含义,仅为普通符号使用,例: \ * \+ \?
    ^ 匹配输入字符串的开始位置
    $ 匹配输入字符串的结束位置
    * 匹配前面的子表达式零次或多次 例: /10*/能匹配1与100
    + 匹配前面的子表达式1次或多次 例: /10+/能匹配10与100但不能匹配1
    ? 匹配前面的子表达式零次或1次 例: /10?/能匹配1与10 但不能匹配100,当?紧跟在 (*, +, ?, {n}, {n,}, {n,m})后时匹配模式是非贪婪的,10+本来可以匹配1000的,10+?则只能匹配10
    {n} 匹配前面的子表达式n次 例: /10{1}/只能匹配10
    {n,m} 匹配前面的子表达式n次到m次 例: /10{1,3}/能匹配10 100 1000
    {n,} 匹配前面的子表达式n次到无数次同+差不多,只是最小匹配次数可以不为1
    . 匹配除换行符(\n、\r)之外的
    (x) 匹配(x)中的x表达式并获取匹配到的结果,使用String.match则可以将一个x表达式的所有(x)匹配获取;例: var str = "http://www.runoob.com:80/html/html-tutorial.html"------------------------------------ var patt1 = /(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/ --------------------------------------------------- str.match(patt1) --------------------------------------------------------------------------------------- // ['http://www.runoob.com:80/html/html-tutorial.html', 'http', 'www.runoob.com', ':80', '/html/html-tutorial.html', index: 0, input: 'http://www.runoob.com:80/html/html-tutorial.html', groups: undefined]
    (?:x) 匹配()中的x表达式但不获取匹配的结果。
    y(?=x) 正向肯定预查,可理解为匹配y后面为x的y。 例: [a-z](?=\d) 表示匹配a2、b4、f5等
    y(?!x) 正向否定预查,可理解为匹配y后面不是x的y。例: [a-z](?!\d) a2、b4等则不匹配,匹配as、a@、s_等
    (?<=x)y 反向肯定预查,可理解为匹配y前面是x的y。 例:(?<=\d)[a-z] 表示匹配2b、3a、4d等
    (?<!x)y 反向否定预查,可理解为匹配y前面不是x的y。 例:(?<!\d)[a-z] 不匹配2b、3a、4d,匹配sa、@a、_d等
    x | y x或y,x不匹配,则去匹配y
    [xyz] 字符集合,匹配所包含的任意一个字符
    [^xyz] 负值字符集合,匹配未包含的任意一个字符
    [a-z] 字符范围,匹配小写字符'a'到'z'范围内的任意一个字符
    \b 匹配一个词的边界,例如单词和空格之间的位置
    \B 匹配一个词的非边界
    \d 匹配一个数字字符,等价于[0-9]
    \D 匹配一个非数字字符,等价于[^0-9]
    \w 匹配一个大小写字母或者数字、下划线,等价于[a-zA-z0-9_]
    \w 匹配一个非大小写字母或者数字、下划线,等价于[^a-zA-z0-9_]
    \f 匹配一个换页符
    \n 匹配一个换行符
    \r 匹配一个回车符
    \s 匹配一个空白字符,包括空格、制表符、换页符和换行符
    \S 匹配一个非空白字符
    \xn 匹配一个ASCII 对应的字符,例:\x41 则匹配A
    \num 其中num是正整数,对应(x)的索引,例如:/(\d)sw([a-z])\1\2/ 其中的\1则表示(\d)匹配的结果 \2则表示([a-z])匹配的结果
    \un 其中n是一个4位的16进制数字,表示匹配Unicode对应的字符,例如:\u00A9 匹配版权符号©,[\u4e00-\u9fa5]则表示匹配汉字的集合

    运算符优先级

    正则表达式从左到右计算,遵循优先级顺序。不同优先级,从高到低计算,相同优先级从左到右计算

    以下表格优先级从高到低排列

    字符 含义
    \ 转义字符
    (), (?:), (?=), [] 圆括号和方括号
    ^, $, \任何元字符、任何字符 定位点和序列(即:位置和顺序)
    | 或操作

    贪婪模式与非贪婪模式

        // 贪婪模式
        const reg = /穷哈{1,2}/
        var str = '穷哈哈哈哈'
        str.match(reg) // ['穷哈哈', index: 0, input: '穷哈哈哈', groups: undefined]
        // 贪婪模式下reg会优先匹配多的,即会匹配{1,2}前的字符2次
        
        // 非贪婪模式
        const reg1 = /穷哈{1,2}?/
        str.match(reg1) // ['穷哈', index: 0, input: '穷哈哈哈', groups: undefined]
        // 非贪婪模式下reg则是优先匹配少的,即会匹配{1,2}前的字符1次
    

    分组

    (x)会存储匹配到的结果,\num元字符则能匹配到对应的结果

        const reg = /([a-z]2) \1/g
        var str = 's5 s2 s2 a2 a2'
        str.match(reg) //  ['s2 s2', 'a2 a2']
    
    很明显([a-z]2)要匹配一个小写字母后跟一个2的字符串,那么reg中有\1,就表示要匹配两个字母跟一个2的字符串
    即:s2 s2或者 a2 a2
    

    使用reaplace获取(x)匹配到的结果

        const reg = /([a-z]1) ([a-z]2)/
        var str = 's1 a2'
        str.replace(reg,'$2 $1') // 'a2 s1'
    
    可以看到$1表示的是第一个(x)匹配的结果,$2是第二个(x)匹配的结果
    

    使用方式

    使用方式分为两类:字符串方法、正则对象下的方法
    常用的方法在本文中有对应的例子,以下仅总结正则的使用方式

    字符串方法(String)

        match、matchAll、search、replace、split
    

    正则对象方法(RegExp)

        test、exec
    

    动态创建正则表达式

    使用RegExp构造函数,第一个参数是正则表达式,第二个参数是修饰符

        const reglist = ['\\w+','\\d+','[a-z]+']
        let str = '2022'
        reglist.forEach(reg=>{
            if (new RegExp(reg,'g').test(str)) {
                console.log('hello'+str)
            }
        })
        // hello 2022 
        // hello 2022
        // undefined
    

    下面附上常用的正则表达式

    正则表达式

    相关文章

      网友评论

          本文标题:一文带你学习正则表达式

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