资讯专栏INFORMATION COLUMN

正则表达式学习

Raaabbit / 537人阅读

摘要:今天我们来讲一下正则表达式的基本使用正则表达式的修饰符执行对大小写不敏感的匹配上面的第一个例子字符串带有大写英文,而我们的匹配方式则为全部小写,我们会得到,第二个例子字符串全部为小写,而匹配方式则为大小写混合也是得到,第三个则是不使用修饰符

今天我们来讲一下正则表达式的基本使用
正则表达式的修饰符

i 执行对大小写不敏感的匹配

   let a = "hEllo World"
   let reg = /hello/i
   console.log(reg.test(a)) // true
   
   let str = "hello"
   let reg1 = /Hello/i
   console.log(reg1.test(str)) // true
   
   let str1 = "hello"
   let reg2 = /Hello/
   console.log(reg2.test(str1)) // false

上面的第一个例子字符串a带有大写英文,而我们的匹配方式则为全部小写,我们会得到true,第二个例子str字符串全部为小写,而匹配方式则为大小写混合也是得到true,第三个则是不使用修饰符i的,得到为false,所以i是对大小写不敏感的

g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)

   let a = "hello hello hello hello"
   let reg = /hello/g
   console.log(a.replace(reg, "*")) // * * * *

   let a1 = "hello Hello hello Hello"
   let reg1 = /Hello/g
   console.log(a1.replace(reg1, "*")) // hello * hello *

   let a2 = "hello Hello hello Hello"
   let reg2 = /Hello/gi
   console.log(a2.replace(reg2, "*"))
   
   let a3 = "hello _Hello hello Hello"
   let reg3 = /Hello/gi
   console.log(a3.replace(reg3, "*"))* _* * *

对于g全局的匹配,我对于它的理解就是能找到的都可以,只要符合的行,看上面的四个例子,最主要是看最后一个一个例子不管是不是一体只要符合你的规则就可以

m 多行匹配

   let a = "hello
 hello hello hello"
   let reg = /hello/m
   console.log(a.replace(reg, "*")) 
   // *
      hello hello hello
   let a1 = "hello Hello
 hello Hello"
   let reg1 = /Hello/m
   console.log(a1.replace(reg1, "*"))
   // hello *
             hello hello

   let a1 = "hello hello
 hello Hello"
   let reg1 = /Hello/m
   console.log(a1.replace(reg1, "*"))
   //hello hello
        hello *

通过上面的两个例子,我们已经知道m修饰符也算是查找全局的修饰符但是它匹配到一个就不会再进行匹配了

es6新增修饰y,又叫做粘连修饰符,和g修饰符类似也是全局匹配

   let str = "anta"
   let y = /a/y
   console.log(str.replace(y, "&")) // &nta
   console.log(str.replace(y, "&")) // anta
   
   let str = "aanta"
   let y = /a/y
   console.log(str.replace(y, "&")) //&anta
   console.log(str.replace(y, "&")) //a&nta
   console.log(str.replace(y, "&")) //aanta

上面第一个例子使用了y修饰符,第一次执行我们匹配到了a替换成功,第二次的时候没有值被匹配到,这是因为y修饰符匹配到一次后,会接着当前匹配到位置的下一个位置开始,所以在第一次替换的时候位置为0,第二次匹配的时候位置则变为了1,y修饰符是具有位置属性的位置匹配,下面我们就来看一下

   let str = "aanta"
   let y = /a/y
   y.lastIndex = 4
   console.log(str.replace(y, "&")) // aant&
   
   y.lastIndex = 1
   console.log(str.replace(y, "&")) // a&nta

上面的两个例子则是使用了位置,我们可以看到使用位置之后,会打乱y修饰符原有的粘连方式,会直接按照我们规定的位置1匹配

   let str = "aanta"
   let y = /a/gy
   console.log(str.replace(y, "&")) // &&nta

上面的例子是g和y修饰符配合使用,会得到我们意想不到的结果,因为它会按照粘连规则检验

RegExp.prototype.sticky 属性检验是否设置了y修饰符

   let y1 = /a/y
   console.log(y1.sticky) // true
   let y = /a/gy
   console.log(y.sticky) // true

RegExp.prototype.flags 属性返回设置的修饰符

   let y1 = /^a/y
   console.log(y1.flags) // y
   let y = /a/gy
   console.log(y.flags) // gy

es6 新增修饰符s 符号.匹配所有字符

    let str = "aa
nta"
    let reg = /a.n/s
    console.log(reg.test(str),reg.dotAll) // true true
    
    let str = "aa
nta"
    let reg = /a.n/
    console.log(reg.test(str),reg.dotAll) // false false

修饰符s匹配换行符n,我们会得到true,如果不用s修饰符的话会匹配不到的,上面的例子中都有检测是否存在dotAll模式中,说白了主要就是看你有没有修饰符s

正则表达式模式

[] 匹配中括号内规则的字符

  let str = "hello world"
  let reg = /[a-z]/
  console.log(reg.test(str)) // true
  
  let str = "hello world"
  let reg = /[a-h]/g
  console.log(str.replace(reg, "*")) // **llo worl*
  
  let str = "he1l3 wo4ld"
  let reg = /[0-9]/g
  console.log(str.replace(reg, "#")) // he#l# wo#ld

上面只是简单的两个例子只是简单的测试下是否可以匹配到中括号内的相关规则字符串

| 匹配多个规则相当于||或

   let str = "he1l3 wo4ld"
   let reg = /[0-9|a-d]/g
   console.log(str.replace(reg, "#")) // he#l# wo#l#
   
   let str = "he1l3 wo4ldc@"
   let reg = /[0-9|a-d|c.]/sg
   console.log(str.replace(reg, "#")) // he#l# wo#l##@

上面第一个例子使用了g修饰符全局匹配0-9内的数字和a-d的字母替换,第二个例子使用了s和g的修饰符

正则表达式元字符

名字 使用描述
/d 匹配数字
D 非数字字符
/s 查找空白字符
S 非空白字符
/b 匹配单词边界
n 匹配换行符
w 单词字符
W 非单词字符
/+ 出现一到多次
$ 匹配结尾
转义
^ 匹配头部出现的
t 匹配制表符
0 查找null

我们按照顺序写几个简单的例子

   匹配数字,只要是数字都能匹配到
   let str = "hello 1235"
   let reg = /d/g
   console.log(str.replace(reg, "*")) // hello ****
   
   查找空白字符
   let str = "hello 1235"
   let reg = /s/g
   console.log(str.replace(reg, "*")) // hello*1235
   
   匹配单词边界
   let str = "hello 1235"
   let reg = //g
   console.log(str.replace(reg, "*")) // *hello* *1235*
   
   匹配换行符
   let str = "hello
123
5"
   let reg = /
/g
   console.log(str.replace(reg, "*")) // hello*123*5
   
   /w匹配[a-zA-Z0-9_]
   let str = "Abv12_$"
   let reg = /w/g
   console.log(str.replace(reg, "*")) // ******
   

匹配结尾的$

    let str = "Abv12"
    let reg = /v$/g
    console.log(reg.exec(str)) // null
    
    let str = "Abv12v"
    let reg = /v$/g
    console.log(reg.exec(str)) // ["v", index: 5, input: "Abv12v", groups: undefined]
    
    ^匹配开头的
    let str = "Abv12v"
    let reg = /^v/g
    console.log(reg.exec(str)) // null
    
    let str = "vAbv12v"
    let reg = /v$/g
    console.log(reg.exec(str)) //["v", index: 0, input: "vAbv12v", groups: undefined]
    
    ^和$配合使用
    let str1 = "abcd 1"
    let reg1 = /^[a-z]+s+d+$/i
    console.log(str1.replace(reg1, "*")) // *

匹配abcd 1,需要对应的规则分别是abcd ^[a-z] 空格s d数字$

{} 和 () 和 ?的使用
    {n} 匹配n个
    {n,} 最少n个
    {n, n} 最少匹配n个,最大匹配n个
    
    ()捕获性分组使用
    
    let str = "2018-03-02"
    let reg = /^(d{4})-(d{2})-(d{2})$/
    console.log(str.replace(reg, "$1/$2/$3")) // 2018/03/02

上面的例子使用了()和{}配合使用,分成了三个组,第一个组匹配四个数字,第二个和第三个匹配两位数字,然后利用了^开始匹配的四位数字开始和$匹配两位数字结束,将-替换/

    ()非捕获性使用 非捕获性分组通过将子表达式放在"?:"符号后,我理解的非捕获性分组就是()有根没有都一样
        let str = "2018-03-02"
        let reg = /^(?:d{4})-(?:d{2})-(?:d{2})$/
        console.log(str.replace(reg, "$1/$2/$3")) // $1/$2/$3

上面的例子就是一个非捕获性的例子,在子表达式前面加上?:就可以解除小括号的分组模式所以匹配不到

贪婪模式与非贪婪模式

说到贪婪模式和非贪婪模式,首先我要介绍一下量词,因为非贪婪模式要用在量词后面

n{X}匹配包含X个n的序列的字符串

n{X,Y}匹配包含X至Y个n的序列的字符串

n{X,}匹配至少包含 X 个 n 的序列的字符串

n*匹配任何包含零个或多个 n 的字符串

n?匹配任何包含零个或一个 n 的字符串

n+匹配任何至少包含一个 n 的字符串

贪婪模式就是尽可能多的匹配
let str = "abcdefghijk123"
let reg = /w{1,4}/
console.log(str.replace(reg, "*")) // *efghijk123

上面的例子则为贪婪模式它会匹配到最大的那个位数

let str = "abcdefghijk123"
let reg = /w{1,4}?/
console.log(str.replace(reg, "*")) // *bcdefghijk123

上面的例子则为非贪婪模式,只会去匹配最少的位数

先行断言和先行否定断言(匹配到前面的)
先行断言?=

let str = "abcdefghijk123asd456"
let reg = /w+(?=123)/g
console.log(str.match(reg)) // ["abcdefghijk"]

上面的例子为先行断言的例子reg规则必须是后面带有123的匹配到

先行否定断言?!

let str = "bbb123 bbbbb456"
let reg = /b{3,}(?!123)/g
console.log(str.match(reg)) // ["bbbbb"]
后行断言和后行否定断言(匹配到后面的)
 后行断言查找匹配表达式匹配到后面的
 
 let str = "abcdefghijk123asd456"
 let reg = /(?<=123)[a-z]/g
 console.log(str.match(reg)) // ["a"]
 
 后行否定断言,匹配不属于123的,后面的[a-z]的字符
 let str = "abcdefghijk123asd"
 let reg = /(?

我感觉先行断言像后行否定断言,先行否定断言像后行断言

RegExp 构造函数对象
 new RegExp(pattern,modifiers)
 pattern 则为表达式
 modifiers 则为修饰符
 
 let reg1 = new RegExp("[a-z]","g")
 console.log(reg1) // /[a-z]/g

上面的例子我们会得到这个结果是因为RegExp对象会将第二个参数修饰符与第一个参数表达式进行合并

let reg1 = new RegExp(/[a-z]/,"g")
console.log(reg1) // /[a-z]/g

上面这个例子我们也会得到我们想要匹配全局的一个表达式,但是在es5中如果这样写就会出现报错

let reg1 = new RegExp(/[a-z]/,"g")
console.log(reg1.flags) // g

let reg1 = new RegExp(/[a-z]/,"i")
console.log(reg1.flags) // i

我们还可以检测表达式是否使用了修饰符,并且可以知道使用了什么修饰符

正则表达式的方法

RegExp 对象方法

compile 编译正则表达式
    let str = "123.jpg456.png"
    let reg = /[123]/g
    console.log(str.replace(reg, "x")) // xxx.jpg456.png
    reg.compile(/[456]/g)
    console.log(str.replace(reg, "x")) // 123.jpgxxx.png
    
    let str = "123.jpg456.png"
    let reg = /[123]/g
    console.log(str.replace(reg, "xx")) // xxxxxx.jpg456.png

上面的第一个例子使用了表达式方法compile它会使表达式重新编译或是修改,所以第一次匹配的是123,第二次则是456,是因为改变了匹配机制,第二个例子使用用到了替换的方法并且会发现你替换的参数多的话会修改字符串的长度

exec 根据正则表达试查找对应的字符和位置
let str = "2018-02-13"
let reg = /-d{1,2}/g
console.log(reg.exec(str)) // ["-02", index: 4, input: "2018-02-13", groups: undefined]

上面的例子是查找带有-数字不超过2位,返回的是数组,并且把匹配到的第一个在最前面的位置

test 根据正则表达试是否匹配到布尔值

正则表达式的 String 对象的方法

search 检索与正则表达式相匹配的值
let str = "2018-02-13"
let reg = /-d{1,2}/g
console.log(str.search(reg)) // 4

它会返回你表达式匹配到第一个字符的位置返回,它会对大小写敏感如果查找不到会返回-1,无视g

match 找到一个或多个正则表达式的匹配
 let str = "this is 1 or 2"
let reg = /d/g
console.log(str.match(reg)) // [1,2]

它会找出所有与你表达式匹配到的字符放入数组中

replace 替换

replace替换我们上面已经使用过很多次了,大家可以仔细阅读看

matchAll 匹配所有,表达式不用使用全局修饰符

es6的正在提案的一个方法,它可以摒弃全局的修饰符,达到全局的匹配,它会返回一个遍历器,然后可以通过结构赋值拿到想要的结果

上面我们学习了那么多,那我们就运用所学写一些表达式
    /^1[3|4|5|7|8][0-9]{9}$/ 匹配手机号开头必须有1,34578其中的一个,结尾必须9位数而且是0-9的数字
    /^0315(-?)[0-9]{7}$/  判断电话区号和-可有可无
    /^[0-9]{4}(-?)[0-9]{7}$/ 匹配1-9的数字必须是四位,可有可无-,匹配7位数字

都是几个比较简单的表达式,还需多学习,多练习才能写出更广泛更精准的表达式

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101224.html

相关文章

  • 正则达式

    摘要:本文内容共正则表达式火拼系列正则表达式回溯法原理学习正则表达式,是需要懂点儿匹配原理的。正则表达式迷你书问世了让帮你生成和解析参数字符串最全正则表达式总结验证号手机号中文邮编身份证地址等是正则表达式的缩写,作用是对字符串执行模式匹配。 JS 的正则表达式 正则表达式 一种几乎可以在所有的程序设计语言里和所有的计算机平台上使用的文字处理工具。它可以用来查找特定的信息(搜索),也可以用来查...

    bang590 评论0 收藏0
  • 正则达式

    摘要:最全正则表达式总结验证号手机号中文邮编身份证地址等是正则表达式的缩写,作用是对字符串执行模式匹配。学习目标了解正则表达式语法在中使用正则表达式在中使 JS高级技巧 本篇是看的《JS高级程序设计》第23章《高级技巧》做的读书分享。本篇按照书里的思路根据自己的理解和经验,进行扩展延伸,同时指出书里的一些问题。将会讨论安全的类型检测、惰性载入函数、冻结对象、定时器等话题。1. 安全的类型检测...

    yibinnn 评论0 收藏0
  • JavaScript正则进阶之路——活学妙用奇淫正则达式

    摘要:正则大法好,正则大法好,正则大法好,重要的事情说三遍。第二部分,这个部分是整个表达式的关键部分。学习正则如果还没有系统学习正则表达式,这里提供一些网上经典的教程供大家学习。正则表达式使用单个字符串来描述匹配一系列匹配某个句法规则的字符串。 原文收录在我的 GitHub博客 (https://github.com/jawil/blog) ,喜欢的可以关注最新动态,大家一起多交流学习,共同...

    BearyChat 评论0 收藏0
  • JavaScript正则进阶之路——活学妙用奇淫正则达式

    摘要:正则大法好,正则大法好,正则大法好,重要的事情说三遍。第二部分,这个部分是整个表达式的关键部分。学习正则如果还没有系统学习正则表达式,这里提供一些网上经典的教程供大家学习。正则表达式使用单个字符串来描述匹配一系列匹配某个句法规则的字符串。 原文收录在我的 GitHub博客 (https://github.com/jawil/blog) ,喜欢的可以关注最新动态,大家一起多交流学习,共同...

    APICloud 评论0 收藏0
  • JavaScript正则进阶之路——活学妙用奇淫正则达式

    摘要:正则大法好,正则大法好,正则大法好,重要的事情说三遍。第二部分,这个部分是整个表达式的关键部分。学习正则如果还没有系统学习正则表达式,这里提供一些网上经典的教程供大家学习。正则表达式使用单个字符串来描述匹配一系列匹配某个句法规则的字符串。 原文收录在我的 GitHub博客 (https://github.com/jawil/blog) ,喜欢的可以关注最新动态,大家一起多交流学习,共同...

    NeverSayNever 评论0 收藏0
  • js正则达式学习笔记

    摘要:说来惭愧,做前端快三年对于正则表达式的应用还是很浅薄,大家都知道正则的速度基本上是最快的,但就是懒得去记那些语法和规则,这次项目中多次用到了需要匹配替换的动作,终于下定决心去研究一下了。 说来惭愧,做前端快三年对于正则表达式的应用还是很浅薄,大家都知道正则的速度基本上是最快的,但就是懒得去记那些语法和规则,这次项目中多次用到了需要匹配替换的动作,终于下定决心去研究一下了。 实例化正则对...

    Towers 评论0 收藏0

发表评论

0条评论

Raaabbit

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<