正则表达式必备
正则表达式(规则表达式) regular expression 简称RegExp

正则字面量里头没有数字和变量的概念,/1/中的1也是字符串 [10]匹配的是1或0;[1-20]匹配的是0或1或2

定义:

一种用于描述某种字符串规则的表达式,内置提供了很多种规则,我们根据这些内置的规则进行组合

js中正则是通过一个对象来创建的。正则是基于字符的操作

  1. 创建对象方式 new RegExp(‘’) 或new RegExp(变量)

    第一个参数为字符串,内部会根据这个字符串构造出一个正则对象

  2. 字面量方式 // 不支持变量

「字面量的意思是它平时长啥样子,你就可以用啥样子去创建它,比如数组是“[]”」

正则就是用于无法简单地用几句话(或确定的字面量)描述出来的场景,处理一些模糊(不那么精确)的需求。

普通字符

元字符(特殊字符)

模式(修饰符)

正则组成:普通字符 + 特殊字符(元字符) + 修饰符(模式)

使用场景

==字符串方法== mssr 主体为字符串,==参数可以为正则==

  • match 匹
  • search 找
  • split 分
  • replace 换

search 返回参数字符在字符串中首次出现位置,类似indexOf;但更牛的是参数可用正则

‘strabc’.search(/\d/)

replace 查找到的字符替换为xx,返回替换后的字符串

‘strabc’.replace(/\d/,‘*’)

替换的新内容参数可以是函数,函数的第一个参数为匹配的完整内容,第二个参数为

split 根据字符串中某个字符切开

‘2a1sdfdfs34as1’.split(/\d+/g)->[“”, “a”, “sdfdfs”, “as”, “”] 切记如果数字在开头分割后会结果会出现空字符串

match 匹配到的内容返回成一个数组

‘str2ab3c’.match(/\d/) ->

==正则对象方法== te特别地 两个

  • test 字符串中有满足正则的内容,就返回true,否则false
  • exec 类似字符串的match方法接正则表达式,但和match主体、参数反过来写

exec方法只会执行一次,然后下一次会继续上次的结果找(没刷新页面),即使加了g也是一次。

string的match方法不一样,他会执行多次。

💡区别:exec方法不加修饰符g影响的是lastIndex(即上次匹配后返回的下标),如果不加g,每次都是从头开始匹配,如果加了g,就从上次的位置开始匹配;用循环匹配时,必须加g呀!或者干脆不用exec还是用match吧

修饰符(模式)

默认情况,正则的匹配是懒惰模式,满足一次匹配后就不动了

g: 代表全局,一直匹配到匹不到了,找到所有匹配才停止。

主要用于搜索和替换,

i: 代表忽略大小写去匹配 但是打印出来不会改变大小写

m: 把str看成多行的,每一行(带\n)都会匹配,而不是只匹配最开始和最末尾

s: dotall模式,.现在也可以匹配换行符了 singleline es8

u: unicode模式,.现在可以匹配unicode字符集了

y: sticky,粘性模式:匹配正则中lastIndex属性指定位置的

字符,并且如果没有匹配也不尝试从任何后续的索引中进

行匹配。例如多次调用exec,每次从上次位置之后一个开始找,这个符合就拿出来,不符合拉倒不找了。

中括号

中括号内的.代表是字面含义,而不是任意一个字符

转义符

两层含义

  1. 把普通字符转为有特殊含义的字符(例如字符串中的t,n等)
  2. 把有特殊含义的字符转为字面量含义(例如正则中的. ? * + 之类, - 横划线容易漏)
行首、行尾、换行符都是不可见(不可描述)字符

‘strabc’.replace(/^/,‘*’) -> 结果不是替换掉s,而是替换掉行首一个看不到的东西,*strabc

零宽单词边界 \b

对\w生效,当\w的左侧或\w的右侧不再是\w,就匹配成功

‘str(abc’.replace(/\b/,‘*’) -> ‘*str*(*abc’

分组(子项) 用括号

str.match(/(ab)(c)d/)

命名分组/(ab)(?\c)d/

然后子项c会出现在结果数组的groups属性中,访问:result.groups.small

捕获子项 ()

非捕获子项 (?:) (只想让括号有分组提高优先级功能,不想让他被捕获到对象子项中(不出现在结果的数组中))

match和exec中使用

零宽断言/预查

断言的内容不会出现在匹配结果中(match出来结果看不到,replace时不会被替换)

==正向断言==

肯定:我断言我之后必定出现符合==条件是condShe的她==(我和她都是判断条件),但是替换的时候只替换我,不替换她。(我受伤就好,请别打扰她) me(?=condShe)

否定:我断言我之后必定出现符合==条件不是condShe的她==(我和她都是判断条件),但是替换的时候只替换我,不替换她。(我受伤就好,请别打扰她) me(?!condShe)

正向断言是跟在后面的,断言我后面会出现的 (?=) (?!)

负向断言是断言我前面会出现的 (es9新特性) (?<=) (?<!)

捕获与零宽断言区别:

捕获:捕获的内容出现在输出结果中但不出现在子项结果(不在数组的子项)中

零宽断言:断言内容完全不会出现在匹配结果中

反向引用

\1表示的是引用第1个子项的内容(即必须和第一个子项的内容保持一致,例如(a)\1相当于匹配aa,但出来的子项还是a)

\2表示引用第2个子项的内容

\n n为正则表达式从左开始数第n个括号

但不会影响子项个数,这个反向引用并不算作子项。

量词

💡 注意贪婪模式与非贪婪模式

{x}匹配x次;等价于{x-y,x}或{x,x+y}? | 贪婪模式与知足模式

+:1到多 | *:0到多 | ?:0到1

+, *, ? 自己都属于贪婪模式 (在==满足自身设定时==)尽可能多地匹配

  • *?: 表示某个模式出现0次到多次,匹配时采用非贪婪模式。只匹配0次(相当于不匹配)
  • +?: 表示某个模式出现1次到多次,匹配时采用非贪婪模式。只匹配1次
  • ??: 表示某个模式出现0次到1次,匹配时采用非贪婪模式。匹配0次(相当于不匹配)

记住一句话,一个符号加上?就变成知足模式了,满足条件时尽可能少地匹配

贪婪非贪婪是match后体现在结果上,但是如果是test,不管是出现少或多次都会为true

几个例子:

‘bbac’.match(/ba*/g)

‘baabac’.match(/ba*/g)

‘baabac’.match(/ba??/g)

‘baaaaabac’.match(/ba{3,5}?/)

☠️坑点☠️
  1. match全局匹配g修饰会忽略子表达式的捕获项,即只返回结果,看不到子项了,也不继承lastIndex

  2. 正则的exec方法使用g修饰是有点残疾的,他忽略了g修饰符的多次匹配特性,但增加了继承上次查找位置的特性(lastIndex是下次匹配从该位置开始查找,会继承),也保留了子项的捕获

    这个可用于==循环匹配(用循环让她有g的效果,记得带上g),而且可以打出子项,match打不出子项==

  3. 量词加上?(最多加1个)可以变为非贪婪模式,??代表匹配0次。

  4. ==行首和行尾其实都可以想象为一个不可见(不可描述)的字符,用\^和$去匹配他==,不要想成\^a为以a开头,不好理解。

  5. 正则字面量//中没有数字和变量的概念,都是字符串。[10]匹配1或0而不是10

  6. 匹配1个中文字符[\u4e00-\u9fa5]

  7. [.]字符簇中的点代表的是真的点

  8. 转义符两层含义:把普通字符转为有特殊含义的字符或把有特殊含义的字符转为字面量含义。

  9. 断言的内容不会出现在匹配结果中(match出来结果看不到,replace时不会被替换)。

  10. 写匹配规则时因为一般都需要添加上行首行尾符^和$。

  11. 用new RegExp构造正则的时候()括号中不用写//字面量了,而是用引号,然后这个时候\w之类的特殊字符需要再加一个\来转义,要写为\\w,(‘\\w+’,‘i’)正确写法

  12. \s\S或者\w\W或者\d\D什么意思?[ab]代表a或b,\s\S代表空白(换行空格tab等)或者非空白,即匹配所有字符!而且比点.还要多,点不匹配换行。\w\W|\d\D也有同样的作用。

xss: 跨站脚本攻击

如果不对一些数据进行过滤的话,会导致该数据被执行(如果该数据是一段可被浏览器执行的脚本)

用正则做匹配处理,处理尖括号

input.value.replace(/<|>/g,function(a){

if(a==“<”){return ‘&lt;’}elseif(a\==“>”){return ‘&gt;’}

})

Author: superman285
Link: https://skr.dog/2018/12/16/正则表达式必备/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.