最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JS中的第二世界--正则表达式

    正文概述 掘金(lebornjose)   2021-03-15   431

    你是不是经常遇到正则,却不知它在说什么,你是不是就算再项目中看到了,也会选择一眼略过,你是不是整天忘记搜索什么,却不知道有的编辑器搜索支持正则的模糊搜索……

    熟悉的旋律萦绕在耳边,却早已不是当初的少年。

    工作了很久之后,猛然发现之前自己忽略的正则是这么重要。搜索、查询、命令行、校验、截取、替换…………哪样哪样都离不开这个小东西。很多人不知道的是,正则在 JavaScript 里仿佛一个第二世界一样。看起来简单,实则有很多让我们摸不着头脑的操作。

    接下来,让我们顺着本文的介绍,一点儿一点儿深入了解正则表达式,知晓正则的强大能力!

    1. 创建正则表达式

    JavaScript 中创建正则表达式有两种方式

    第一种:构造函数创建

    const reg = new Reg('正则表达式')
    

    第二种:字面量创建

    const reg = /正则表达式/
    

    2. 使用正则表达式匹配内容

    正则匹配分为 精准匹配模糊匹配

    精准匹配

    只需要我们将需要匹配的内容放入到正则表达式中匹配即可。上手简单

    const reg = /正则表达式/
    const str = '这是一篇写正则表达式是文章'
    
    str.match(reg) // 正则表达式
    

    这里的正则表达式会精准的搜索到我们要搜索的内容。

    模糊匹配

    模糊匹配需要用到第三点所描述的内容,这里我们先看下

    const reg = /[\u4e00-\u9fa5]+/
    const str = '这是一篇写正则表达式Regpx的内容'
    
    str.match(reg) // 这是一篇写正则表达式
    

    这里的正则表达式会根据我们传入的规则来匹配要搜索的内容。**注意:**这里的\u4e00-\u9fa5表示的是中文范围

    \u4e00 表示的是字符集中第一个中文汉字

    \u9fa5 表示的是字符集中最后一个中文汉字

    ok,知道了怎么创建和使用正则,接下来我们来真正了解一下他吧。

    3. 正则表达式介绍

    通晓元字符的同学可跳过此小节,直奔第四小节查看。主要内容有 . | \ * + ? () [] {} ^ $ 几种字符使用方法,含义和注意事项,内置匹配项,贪婪和惰性匹配

    首先介绍一下前瞻条件,正则可以根据自己的设置来进行多行和全局,局部,忽略大小写等匹配模式,分为:

    • m :多行匹配
    • g: 全局匹配
    • i: 忽略大小写

    接下来的内容,就可以看到我们来使用它

    3.1 元字符

    元字符是正则表达式中最基础的部分,它代表了我们可以查询的内容。come on baby。让我们来认识一下他们吧。

    • . :匹配除去 \n 之外的所有内容

      const reg = /.*/ const str1 = 'abc'

      // 在str2中添加 \n 换行符 const str2 = 'a\nb\nc'

      str1.match(reg) // abc str2.match(reg) // a

    • |:在正则中进行逻辑判断,(说的比较抽象,我们来看下例子)

      const reg = /正则|表达/ const str1 = '正则表达式' const str2 = '表达式'

      str1.match(reg) // 正则 str2.match(reg) // 表达

    解释:

    如果可以匹配到 | 前边的内容,则匹配前边的。

    匹配不到前边的,但是可以匹配后边的内容,则匹配后边的

    • 反斜杠 \ :表示转义

      const reg = /./ const str = 'a.b.c.d'

      str.match(reg) // .

    可以匹配除 \n 外任意字符的点 . 在使用 \ 转义之后只能匹配到 . 这个字符

    需要注意的点:

    在有的编程语言中,匹配 \\ 需要四个反斜杠 -- \\\\。但是在 javascript 中,只需要两个。

    const reg = /\\/
    const str = '\\'
    
    str.match(reg) // \\
    
    • 星号 *:需要匹配的内容出现连续零次或多次

      const reg = /a*/ const str1 = 'aaabbcccddd' const str2 = 'bbcccddd' reg.test(str1) // true reg.test(str2) // true

    • 加号 +:需要匹配的内容出现连续一次或多次

      const reg = /a+/ const str1 = 'aaabbcccddd' const str2 = 'bbcccddd' reg.test(str1) // true reg.test(str2) // false

    • 问号 ?:需要匹配的内容出现连续零次或一次

      const reg = /a?/ const str1 = 'aaabbcccddd' const str2 = 'bbcccddd'

      reg.test(str1) // true reg.test(str2) // true

    • 小括号(): 表示组,小括号中的内容表示一组,整体进行匹配。

      const reg = /(abc)/ const str1 = 'abab' const str2 = 'abcab' reg.test(str1) // false reg.test(str2) // true

    拓展:

    使用小括号包裹的匹配内容,可在后续的正则中通过\ + 序号的方式继续调用。有几个小括号就有几个序号。序号从1开始

    const reg = /(abc)\1/  // 相当于 const reg = '(abc)abc'
    const str = 'abcabc'
    
    str.match(reg)
    
    //   /(a)(b)(c)\1\2/ ---> /(a)(b)(c)ab/
    
    • 中括号 []:表示范围,括号中的内容只要有一个匹配到就可以

      const reg = /[abc]/ const str = "efg" const str1 = 'aef'

      reg.test(str) // false reg.test(str1) // true

    注意:

    中括号中可以使用 - 来表示连续的范围

    /[0-9]/   0123456789
    /[a-z]/   全部英文小写
    /[A-Z]/   全部英文大写
    
    • 大括号 {m,n}:表示出现次数

    m 表示最少出现多少次 n表示最多出现多少次,n可省略,表示无限次

    const reg = /a{1,4}/ // a最少出现1次,最多出现4次
    const str = 'aaaaa'
    
    reg.test(str) // true
    

    拓展:

    {0,} 相当于 *

    {1,} 相当于 +

    {0,1}相当于 ?

    • 开头^:只匹配开头内容

      const reg = /a^/ const str = 'abc' const str1 = 'bac'

      reg.test(str) // true reg.test(str1) // false

    注意:

    此符号用在 [] 中,表示取反操作

    const reg = /[^abc]/g 
    const str = '123'
    str.match(reg) // ['1', '2', '3']
    

    这里只能取到不是 abc 的内容

    • 结尾$: 只匹配结尾

      const reg = /a$/ const str = 'abc' const str1 = 'cba'

      reg.test(str) // false reg.test(str1) // true

    3.2 内置匹配符

    \d:数字

    \D:非数字

    \s:空格

    \S:非空格

    \w:数字字母下划线

    \W:非数字字母下划线

    \b:字符边界

    \B:非字符边界

    const str = 'hello word! 520'
    
    console.log(str.replace(/\d/g, '*')) // hello word! ***
    console.log(str.replace(/\D/g, '*')) // ************520
    console.log(str.replace(/\w/g, '*')) // ***** ****! ***
    console.log(str.replace(/\W/g, '*')) // hello*word**520
    console.log(str.replace(/\b/g, '*')) // *hello* *word*! *520*
    console.log(str.replace(/\B/g, '*')) // h*e*l*l*o w*o*r*d!* 5*2*0
    console.log(str.replace(/\s/g, '*')) // hello*word!*520
    console.log(str.replace(/\S/g, '*')) // ***** ***** ***
    

    3.3 贪婪和惰性

    贪婪匹配是最多情况下匹配内容

    惰性匹配是最少情况下匹配内容

    先看栗子

    const reg = /a[bc]*c/g  // 贪婪
    const str = 'abcbcbc'
    
    console.log(str.match(reg)) // [ 'abcbcbc' ]
    
    const reg1 = /a[bc]*?c/g // 惰性
    console.log(str.match(reg1)) // [ 'abc' ]
    

    解释:

    • 贪婪: 由于 abcbcbc 一直到字符串最后都符合正则的规则,所以一直匹配到不符合位置
    • 惰性:只匹配一个符合规则的就返回,不继续匹配。

    4. 正则进阶操作

    4.1 具名组匹配

    JavaScript 中提供了组匹配的能力。可以同过自定义的组名来获取匹配内容.

    组的固定格式为 ?<组名>。然后通过获取结果的groups.具体的名称 来获取

    const reg = /(?<name>[a-zA-Z]{3,6})(?<age>\d{2})/
    const str = 'xiaoming23'
    
    str.match(reg).groups.name // xiaoming
    str.match(reg).groups.age // 23
    

    4.2 位置匹配

    • ?=搜索内容:查看右侧内容是否符合条件, 查看后缀是否为要搜索的内容。

      const reg = /(?=abc)/ const str = 'efabcefabc'

      str.replace(reg, '') // efabcef*abc

    解释:

    匹配 后缀为abc 这个字符的位置

    • ?!搜索内容:查看右侧内容是否不符合条件,查看后缀是否为要搜索的内容

      const reg = /(?!abc)/ const str = 'efabcefabc'

      str.replace(reg, '') // efabcefabc

    解释:

    匹配 后缀不为 abc 这个字符的位置

    • ?<=搜索内容:查看左侧内容是否符合条件,查看前缀是否是要搜索的内容

      const reg = /(?<=abc)/ const str = 'efabcefabc'

      str.replace(reg, '') // efabcefabc*

    解释:

    匹配 前缀为abc 这个字符的位置。

    • ?<!搜索内容:查看左侧内容是否不符合条件

      const reg = /(?<!abc)/ const str = 'efabcefabc'

      str.replace(reg, '') // efabcefabc

    解释:

    匹配 前缀不为abc 这个字符的位置。

    第四小节总结:

    1. 组匹配 ?<组名>
    2. 匹配后缀 ?=?!
    3. 匹配前缀 ?<=?<!

    5. 正则和字符串方法介绍

    5.1 字符串方法

    下述方法都支持正则匹配方式来操作。

    • replace(reg, 替换的内容 或者 一个操作函数) 替换

    此方法的第二个参数是比较神奇的,可以接收要替换的内容,也可以接受一个函数。

    • 为替换内容(1)

      const str = 'abc'
      str.replace(/a/, '*') // *bc

    • 为替换内容(2)
      可使用 $1,$2………… 等变量作为匹配到的组的内容。

      const str = '123abc'
      str.replace(/(a)(b)(c)/, '1113$2') // 123acb

    说明:

    $1 代表 (a) 所匹配到的内容

    $2 代表 (b) 所匹配到的内容

    $3 代表 (c) 所匹配到的内容

    替换的时候掉到顺序替换,则输出 123acb 这个值

    • 为函数

      const str = 'abc'
      str.replace(/(a)/, (source, 1, index) => { console.log(source, 1, index) // abc a 0 return '*' }) // *ab str.replace(/(b)(c)/, (source, 1,1, 1,2, index) => {
      console.log(source, 1,1, 1,2, index) // abc b c 1
      return $1 + 1
      }) // a11

    说明:

    函数参数接收的参数,第一个source 为字符串本身,最后一个index为查找到的第一个索引值。中间的 $1, $2, $3……………… 为正则表达式里小括号的数量。返回值的作用是作为替换内容替换原字符串。

    • match 搜索

    根据正则的规则匹配字符串

    const reg = /[abc]/g
    const str = 'abc'
    str.match(reg) // [ 'a', 'b', 'c' ]
    
    • split 切割

      const str = 'abcabcabc' str.split(/ca/) //[ 'ab', 'b', 'bc' ]

    此方法还可接收第二个参数。length 设置返回的数组长度

    const str = 'abcabcabc'
    str.split(/ca/, 2) //[ 'ab', 'b' ]
    

    5.2 正则方法

    • test 查看字符串是否符合正则规则

      const reg = /abc/
      const str = 'abc'
      const str1 = 'ab'

      reg.test(str) // true
      reg.test(str1) // false

    • exec 根据正则的规则匹配字符串。同 match

      const reg = /abc/
      const str = 'abc'
      const str1 = 'ab'

      reg.exec(str) // 'abc'
      reg.exec(str1) // null

    6. 实战篇

    理解了内容之后怎么也得练练手啊,此内容给大家准备了几个常见但是不太好理解的正则,请大家练手。

    6.1 匹配 html 标签 (包含标签中的内容)

    首先,我们来创建个字符串

    const html = '<div></div>'
    

    现在我们来抒写一下可描述标签的正则表达式。有以下几个特征:

    1. < 开头
    2. 标签名为英文字符
    3. </标签名> 结尾

    第一版表达式

    const reg = /<(\w+)><\/(\1)>/g
    
    // 验证一下
    html.match(reg) // '<div></div>'
    

    \1引用上一个分组的正则规则上面的内容已经说过。

    看我们的验证结果,完美。但是,有个问题。我们的标签一般都不在一行内书写,标签之间会有 \n 来标识换行。ok,让我们修改一下 html 字符串

    const html = `<div>
    
    </div>`
    
    // 再次验证
    html.match(reg) // null
    

    ?完了,失败了。

    不要着急,我们只匹配了标签,并没有匹配到标签中的内容。由于 . 并不能匹配到 \n 所以我们使用其他条件来匹配。

    第二版表达式

    const reg = /<(\w+)>([\s\S]*)<\/(\1)>/g 
    
    // 验证
    html.match(reg) // '<div>\n\n</div>'
    

    (^o^)/,成功。

    这里我们可以看到。使用 [\s\S] 可以匹配到 \n。因为 [\s\S] 代表的是空格和非空格。相同的用法还有 [\w\W]、[\b\B]、[\d\D]

    第三版表达式

    html 除了双标签还有单标签,下面我们来看下单标签的验证。单标签的开始跟双标签一样。但是结束不一样,单标签是以/>结束。不说了,先写一下

    let reg = /<(\w+)/    // 相同的开头
    
    // 结束规则书写
    reg = /<(\w+)\/>/
    

    注意,这里,单标签中的内容,我们不需要用 [\s\S] 这种方法验证,会有其他问题,因为我们需要匹配的是属性,匹配到换行符结束。所以下面这种写法就可以。

    reg = /<(\w+)([^>]*)\/>/
    

    [^>] 表示只要不是结束符号的,都符合条件。* 表示出现零次或多次

    不说了,我们来验证下

    const html = '<img src="" />'
    html.match(reg) // <img src="" />
    

    ?,成功。

    结合版(不是终极版)

    结合版的正则表达式我们需要用到元字符中的|来作为分支判断

    const reg = /<(\w+)>(([\s\S]*)<\/(\1)>)|(([^>]*)\/>)/mg
    // (([\s\S]*)<\/(\1)>) 双标签
    // (([^>]*)\/>)单标签
    

    说明:m 的作用是来表示匹配多行。g 的意思是表示全局匹配

    验证一下

    const html = '<div ></div><p></p><img src="asfs" /><br />'
    
    html.match(reg)
    // [ '<p></p>', '<img src="asfs" />', '<br />' ]
    

    成功!!

    虽然这次的匹配成功了,但是这个表达式还是有很多问题,期待读者来完善哟。

    6.2 实现数字千分位

    同样,我们来分析一下需求。千分位是每隔三个数字,加上一个逗号。首先,我们先创建一个数字的字符串

    const str = '12345678'
    

    查看后缀是否是三个数字,我们使用 ?= 来做,它的作用就是查看后缀是否符合规则。先来创建正则

    第一版

    const reg = /(?=\d{3})/g
    

    因为需要匹配整个数字,所以我们用到了 g 来表示全局匹配。好,正则创建完成,验证一下。

    str.replace(reg, ',') // ,1,2,3,4,5,678
    

    整个结果,好像有问题啊。

    不着急,继续向下看,由于我们要数字三个一对的出现,所以这里我们需要添加出现一次或多次的校验。使用+

    第二版

    const reg = /(?=(\d{3})+)/g
    

    先不急着验证,因为还没有完成。由于每三个字符是一个节点,所以这里还需要用 $ 来表示查找结束。

    第二版改进

    const reg = /(?=(\d{3})+$)/g
    

    验证:

    str.replace(reg, ',') // 12,345,678
    

    貌似是成功了,多来验证几次。

    …………

    验证到这个字符串时出现问题。

    const str = '123456789'
    str.replace(reg, ',') // ,123,456,789
    

    这里我们看到,数字正好是九位,所以开始的 123 也符合条件。所以需要吧开头禁止掉。使用 ?!这种方式

    第三版

    const reg = /(?!^)(?=(\d{3})+$)/g
    

    再次验证:

    str.replace(reg, ',') // 123,456,789
    

    7. 总结

    好了,本次的内容我们就先分享到这里了,期望你能从这篇文章中真正了解到正则表达式。本篇文章一共分享了一下几个内容

    • 元字符
    • 位置匹配
    • 字符串和正则表达式方法讲解
    • 实战操作

    正则的使用方式千变万化。所谓能力越大,危害就越大,只有真正掌握了它,才能在实际应用中得心应手,否则容易造成不小的祸端。


    起源地下载网 » JS中的第二世界--正则表达式

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元