关于正则表达式:JS中的第二世界正则表达式

37次阅读

共计 7305 个字符,预计需要花费 19 分钟才能阅读完成。

近期的忙碌让我始终没有闲暇静下心来好好写一些文章。好在,所有的繁忙都已过来,愿今天更美妙。刚过完七夕,带着欢畅的情绪写下这篇文章。心愿读者可能喜爱哟~~

你是不是常常遇到正则,却不知它在说什么,你是不是就算再我的项目中看到了,也会抉择一眼略过,你是不是终日遗记搜寻什么,却不晓得有的编辑器搜寻反对正则的含糊搜寻……

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

工作了很久之后,猛然发现之前本人疏忽的正则是这么重要。搜寻、查问、命令行、校验、截取、替换…………哪样哪样都离不开这个小东西。很多人不晓得的是,正则在 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, '*') // ef*abcef*abc

解释:

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

  • ?! 搜寻内容 :查看 右侧 内容是否不符合条件,查看后缀是否为要搜寻的内容
const reg = /(?!abc)/
const str = 'efabcefabc'

str.replace(reg, '*') // *e*fa*b*c*e*fa*b*c*

解释:

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

  • ?<= 搜寻内容 :查看 左侧 内容是否符合条件,查看前缀是否是要搜寻的内容
const reg = /(?<=abc)/
const str = 'efabcefabc'

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

解释:

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

  • ?<! 搜寻内容 :查看 左侧 内容是否不符合条件
const reg = /(?<!abc)/
const str = 'efabcefabc'

str.replace(reg, '*') // *e*f*a*b*ce*f*a*b*c

解释:

匹配 前缀不为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)/, '$1$3$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, $2, index) => {console.log(source, $1, $2, index) // abc 
        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 = '![]()'
html.match(reg) // ![]()

????,胜利。

联合版(不是终极版)

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

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

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

验证一下

const html = '<div title="1"></div><p></p>![](asfs)<br />'

html.match(reg)
// ['<p></p>', '![](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. 总结

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

  • 元字符
  • 地位匹配
  • 字符串和正则表达式办法解说
  • 实战操作

正则的应用形式变幻无穷。所谓能力越大,危害就越大,只有真正把握了它,能力在理论利用中得心应手,否则容易造成不小的祸端。

那么,再见了,敬爱的读者敌人们,期待下次相遇~~

正文完
 0