一文带你学习正则表达式

2022-01-21  本文已影响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

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

正则表达式

上一篇下一篇

猜你喜欢

热点阅读