从零开始学正则

问题:我怎么才能收到你们公众号平台的推送文章呢?

正则规范

正则表达式的英文是regular expression简称regex。正则表达式就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,并让计算机用这个规则去检索符合规则的文本。正则表达式主要有两个派别,一个是POSIX标准,使用这个标准的主要是linux系列的系统里的工具比如sed、awk等等;还有一个是PCRE,这个表达式在编程语言里运用很广泛,比如php、java都是用PCRE,PCRE的功能比POSIX强很多。js就是用的PCRE。用JS创建第一个正则1.利用RegExp2.利用反斜杠options的取值有以下两种:,忽略大小写,匹配全局,可能有多个匹配结果正则学习正式开始一个简单的正则表达式可以是最普通的字符串,举一个最简单的例子,abc是一个字符串,我们认为abc就是我们的规则,那么,正则就可以写成 。当然实际场景不可能这么简单,实际场景可能更加复杂,下面将会慢慢介绍具体的定义规则的用法。. 的用法如果要匹配 aXb 这样的字符串,其中 X 表示可以是任意一个字符,注意是,一个字符,那么可以写成

/a.b//a.b/.test('aHb')---true/a.b/.test('aHHb')---false

中间的 . 表示可以匹配任意一个字符* 的用法

/a*b//a*b/.test('b')---true/a*b/.test('ab')---true/a*b/.test('aaab')---true

中间的 * 表示把星号前的字符匹配0次或多次+ 的用法

/a+b//a+b/.test('b')---false/a+b/.test('ab')---true/a+b/.test('aaab')---true

表示前面的字符匹配1次或多次,这个表达式和 /aa*b/ 是完全一样的

? 的用法

/a?b//a?b/.test('b')---true/a?b/.test('ab')---true/a?b/.test('aaab')---false

? 表示前面的字符匹配0次或1次*、+ 和 ? 的匹配属于贪婪模式比如需要用 去匹配 的话,从第一个字母看起来这个表达式可以匹配 和 , 那到底是匹配哪个?“贪婪模式” 的意思就是,会尽可能多的匹配。正则中的 是符合贪婪模式的,所以它会匹配到后者,因为后者的字符串更长.

'abcccccccbcc'.replace(/a.*b/,'Q')---"Qcc"'abcccccccb'被匹配中了,并replace成了Q

如何将贪婪模式转为非贪婪模式?

“非贪婪模式” 的意思就是,会尽可能少的匹配。做法就是在 、、 的后面再加一个问号比如需要用 去匹配 的话,从第一个字母看起来这个表达式可以匹配 和 , 那到底是匹配哪个?这次,显然是匹配到前者。

'abcccccccbcc'.replace(/a.*?b/,'Q')---"Qcccccccbcc"'ab'被匹配中了,并replace成了Q

* 和 + 匹配的字符可以是无穷个,如何指定匹配次数?

和 匹配的字符个数没有上限,但是可以通过来指定匹配次数↑↑↑ 把a匹配5次,效果和和/aaaaa/是完全一样的。↑↑↑ 把 a 匹配1~6次,可以匹配a、aa、aaa、aaaa、aaaaa和aaaaaa。↑↑↑ 把a匹配 ≥ 3 次,可以匹配aaa、aaaaaaaaaa等等。效果和 /aaaa*/ 或者 /aaa+/ 完全一样。如何指定开始匹配的位置?那如果我要设置【以某某规则开头】的规则,如何设置?答案是:使用 ^那如果我要设置【以某某规则结尾】的规则,如何设置?答案是:使用 $使用 ^ 设置【以某某规则开头】的规则使用 $ 设置【以某某规则结尾】的规则还有限制匹配到字符串末尾:同时使用 $ 和 ^把^和$一起用的话就可以限制整个字符串都要符合正则表达式利用 [] 指定一个字符的匹配规则我们可以利用 [] 指定一个字符的匹配规则,记住!! [] 只占一个字符的位子!!但是这个位子上的字符匹配的可能性,可以在 [] 中随意指定匹配的范围。如果要匹配某个位子上多个可能出现的字符指定 a 和 c 之间,只能出现 b 或 B

/a[bB]c/.test('abc')---true/a[bB]c/.test('aBc')---true/a[bB]c/.test('abbc')---false/a[bB]c/.test('aac')---false

如果要匹配某个位子上多个可能出现的数字

/a[0-9]c/.test('a1c')---true/a[0-9]c/.test('a11c')---false/a[0-9]c/.test('abc')---false

[] 所匹配到的规则

上文中 表示可以匹配一个一位整数,这个是和字符编码有关的。0的编码是48,1的编码是49,以此类推,9的编码是57,所以0-9的编码,正好是连续的编码,所以可以用0-9表示匹配一个数字。就可以匹配a0c、a1c、...... 、a9c方括号里面也可以多种方式混合使用

/a[bB0-9]c/.test('a1c')---true/a[bB0-9]c/.test('abc')---true

就可以匹配abc、aBc和a0c、a1c、...... 、a9c在 [] 中使用 ^,能对 [] 中的规则取反如果在方括号里面加上^的话,就表示匹配 “所有不包含在方括号内的字符

/a[^0-9]c/.test('a1c')---false/a[^0-9]c/.test('abc')---true/a[^0-9]c/.test('a=c')---true

,表示匹配一个非数字,比如abc、a=c ...... ,但是不能匹配a0c、a1c、...... 、a9c如何指定匹配多个符合 [] 规则的字符因为[]指定了一个字符的规则,如果想要多个符合[]内规则的字符,只需要在 [] 后面跟一个 + (匹配1个或多个), 或跟上 * (匹配0个或多个)也可以在 [] 后面跟上 {} 来指定个数, 如 表示匹配2~6个数字利用 | 指定匹配多个字符串相当于是 “” 的意思,常用场景比如匹配可能出现的文件后缀

/doc|xls|ppt/---匹配docxlsppt/html|css|js/---匹配htmlcssjs

| 的优先级很低很低

的优先级比“连接”(就是字符串)低,如要在正则的字符串里使用 的话要加括号,提高优先级。比如要匹配wow, he is good 或者 wow, she is good.最好这样写:/wow, (she|he) is good./使用 () 指定一个捕获组括号除了能够提高匹配规则的优先级,还有一个作用,就是充当“捕获组”。比如要匹配html的标签可以这样写:,表示要完全匹配正则里第一个 () 里的规则的内容,比如第一个 () 里的表达式匹配了body,那\1的部分也要完全匹配body捕获组 () 最多9个, \1 ~ \9 分别与这9个 () 按顺序一一对应在replace中使用捕获组捕获组也可以在replace里面用。比如要把 里的变量名前面都加上 :

'result = first + second - third'.replace(/([a-z]+)/g,'!$1')// "!result = !first + !second - !third"

在replace的第二个参数里,利用是 引用捕获组。但如果要把 里的变量名前面都加上 怎么办呢?

'result = first + second - third'.replace(/([a-z]+)/g,'$$1')// "$1 = $1 + $1 - $1" 这个结果不是我们想要的

所以规定,要在 这样的关键字前面使用 这个字符本身的话,要用, 所以:

'result = first + second - third'.replace(/([a-z]+)/g,'$$$1')// "$result = $first + $second - $third"

所以,上面的, 第1-2位是一个整体,表示一个普通的字符串,第3-4位是一个整体,表示捕获组。在exec中使用捕获组使用正则的exec方法,可以取出exec中字符串匹配的部分

//.exec("111

222

333")//["

", "br", index: 3, input: "111

222

333"]/^(\w+)\.(jpg|jpeg|bmp|png|gif)$/i.exec('_dsa.png')//["_dsa.png", "_dsa", "png", index: 0, input: "_dsa.png"]

返回值是一个数组。数组第1个元素是匹配到的字符串结果,数组第2个元素是匹配到的第1捕获组的内容,数组第n个元素是匹配到的第(n - 1)捕获组的内容,数组倒数第2个元素是匹配到的捕获组的起始下标,数组倒数第1个元素是被exec执行匹配的字符串。常用的简写我们发现,实际场景中经常需要匹配数字,、 写起来太累了,有什么简写可以直接匹配到数字吗?或者还有哪些常用简写吗? 有的有的。[0-9] 的简写[0-9]可以用来表示一个一位整数,它有自己的简写,。如 表示匹配2~6个数字, 可以写成 再如 可以写成空白符的简写表示空白符,就是空格、tab这些不会显示出来的符号

'H E L L O'.replace(/\s/g,'')---"HELLO"

匹配_、数字或字母的简写

表示_、数字或字母

'_123ABC..:‘'.replace(/\w/g,'Q')---"QQQQQQQ..:‘"

简写是区分大小写,那么大写啥意思?

如果把、 的字母换成大写就相当于是取反,比如 表示匹配 “不是数字的字符”比如 表示匹配 “不是_、数字或字母的字符

'_123ABC..:‘'.replace(/\w/g,'Q')---"QQQQQQQ..:‘"'_123ABC..:‘'.replace(/\W/g,'Q')---"_123ABCQQQQ"

使用正则关键字前,请使用转义

比如,现在需要写出js的变量命名规则:以、 或字母开头,后面跟上0个或多个、、字母或数字。

/^[\$_a-zA-Z][\$_0-9a-zA-Z]*$/i

因为字符在正则表达式里是个特殊字符,所以要表达“匹配$字符”的话就要把字符转义,就是在$前面加一个,变成像、、、、、、、、、 等等这些关键字符号,如果要匹配这些字符就要转义。小练习① 编写一个正则表达式,判断一个文件名的后缀是不是doc、xls或ppt。② 编写一个匹配坐标的正则表达式。一个坐标的形式是(a,b),其中a和b都是任意位数的数字,也可能为负数。③ 编写一个匹配IP地址的正则表达式。IP地址的形式为a.b.c.d,其中a,b,c,d都是一个0到255之间的数字(包含0和255,如果有多个0的话也算0,比如000和00都可以)④ 编写一个匹配图片文件名的正则。图片文件名的形式为: 名称.后缀名,其中名称可以是任意的字符串,但不能为空;后缀名可以是jpg,jpeg,bmp,png和gif,不区分大小写⑤ 承接上题,把匹配的图片文件名里的“名称”和“后缀名”部分取出来。比如abc.jpeg的名称和后缀名分别为“abc”和“jpeg”(提示:使用exec方法)⑥ 承接上题,把匹配的图片文件名替换为“File XXX is a YYY file.”的形式,其中XXX是“名称”部分,YYY是“后缀名”部分。

公布答案

① 编写一个正则表达式,判断一个文件名的后缀是不是doc、xls或ppt。

/^\w+\.(doc|xls|ppt)$/.test('_dsa.xls')

② 编写一个匹配坐标的正则表达式。一个坐标的形式是(a,b),其中a和b都是任意位数的数字,也可能为负数。

/^\(-?\d+,-?\d+\)$/.test('(23,-4324)')

③ 编写一个匹配IP地址的正则表达式。IP地址的形式为a.b.c.d,其中a,b,c,d都是一个0到255之间的数字(包含0和255,如果有多个0的话也算0,比如000和00都可以)。

/^(\d)|([01]\d)|([2][0-4]\d)|(25[0-5])$/.test(256)/^((\d\.)|([01]\d\.)|([2][0-4]\d\.)|(25[0-5]\.))((\d)|([01]\d)|([2][0-4]\d)|(25[0-5]))$/.test('25.244.244.000')

④ 编写一个匹配图片文件名的正则。图片文件名的形式为: 名称.后缀名,其中名称可以是任意的字符串,但不能为空;后缀名可以是jpg,jpeg,bmp,png和gif,不区分大小写

/^\w+\.(jpg|jpeg|bmp|png|gif)$/i.test('_dsa.Png')

⑤ 承接上题,把匹配的图片文件名里的“名称”和“后缀名”部分取出来。比如abc.jpeg的名称和后缀名分别为“abc”和“jpeg”

/^(\w+)\.(jpg|jpeg|bmp|png|gif)$/i.exec('_dsa.png')

⑥ 承接上题,把匹配的图片文件名替换为“File XXX is a YYY file.”的形式,其中XXX是“名称”部分,YYY是“后缀名”部分。比如abc.jpeg会替换为“File abc is a jpeg file”。

'_dsa.png'.replace(/^(\w+)\.(jpg|jpeg|bmp|png|gif)$/i,"File $1 is a $2 file.")

关注我们

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20171210B0MMX900?refer=cp_1026

相关快讯

扫码关注云+社区