正则表达式笔记,帮你打通任督二脉

前言

说句实话的,自从我整理这篇笔记后,基本上项目里遇到的所有正则匹配的问题,不论多复杂,只要回过头看这篇笔记,理解透彻,基本上都能解决的。这里关于深内容的描述,我这边也举了不少内容帮助大家理解。

这是一篇男女老少入门精通咸宜的正则笔记。

正则表达式是什么?

字符是计算机软件处理文字时最基本的单位,字符串是0个或更多个字符的序列。
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具,就是来用于匹配字符串中字符组合的模式。

怎么创建?

正则表达式字面量
/ pattern / flag
调用RegExp对象的构造函数
new RegExp(pattern, flag)
这里的pattern,有三种形式:

  1. 参数变量
  2. 带引号的匹配模式
  3. 带//的匹配模式

注意:带引号的方式,需要常规的字符转义规则(在前面加反斜杠 \),而带//的方式,则跟字面量形式一样。

E.g. 都表示同一个规则

var re = new RegExp("\\w+");
var re = new RegExp(/\w+/);
var re = /\w+/;

flag标识

如果指定,标志可以具有以下值的任意组合:

g : 全局匹配;找到所有匹配,而不是在第一个匹配后停止

i : 忽略大小写

m : 多行; 将开始和结束字符(^和$)视为在多行上工作(例如,分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处。

区别:
当正则表达式保持为常量时使用字面量;如果你知道正则表达式模式将会改变,或者你事先不知道什么模式,而是从另一个来源获取,如用户输入,这些情况都可以使用构造函数。

规则

简单匹配,精确匹配
常见的特殊字符

特殊字符 描述
\b 匹配一个词的边界。\b匹配这样的位置:它的前一个字符和后一个字符不全是(一个是,一个不是或不存在)\w。注意,一个匹配的词的边界并不包含在匹配的内容中。换句话说,一个匹配的词的边界的内容的长度是0。
\w 匹配一个单字字符(字母、数字或者下划线)
\s 匹配一个空白字符,包括空格、制表符、换页符和换行符。
\d 匹配一个数字。匹配的是正整数,且匹配检查的对象是数字类型时,如1. 会当成1 处理,即/^\d$/.test(1.)返回true,/^\d$/.test(‘1.’)返回false;
. (小数点)匹配除换行符之外的任何单个字符。
[\u4e00-\u9fa5] 匹配汉字
匹配前面一个表达式0次或者1次。等价于 {0,1}。如果紧跟在任何量词 *、 +、?或 {} 的后面,将会使量词变为非贪婪的(匹配尽量少的字符),和缺省使用的贪婪模式(匹配尽可能多的字符)正好相反。
* 匹配前一个表达式0次或多次。等价于 {0,}。
+ 匹配前面一个表达式1次或者多次。等价于 {1,}。
{n} n是一个正整数,匹配了前面一个字符刚好发生了n次
{n,m} n 和 m 都是正整数。匹配前面的字符至少n次,最多m次。如果 n 或者 m 的值是0, 这个值被忽略。
^ 匹配输入的开始。如果多行标志被设置为true,那么也匹配换行符后紧跟的位置。当’^'作为第一个字符出现在一个字符集合模式时,它将表示“非”
$ 匹配输入的结束。如果多行标示被设置为true,那么也匹配换行符前的位置。
| x|y,匹配‘x’或者‘y’。匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。
[ ] 一个字符集合。匹配方括号的中任意字符,包括转义序列。你可以使用破折号(-)来指定一个字符范围。不过[.?!*]匹配标点符号(.或?或!或*)。他们不必进行转义,不过转义也是起作用的。以下为所有可以在[]里进行转义为普通字符串的字符:.[*?+^$|()/
[^] 当 '^'作为第一个字符出现在一个字符集合模式时,它将表示“非”。而且是对于其后的所有表达式整体取非,而不是紧接其后的一个表达式。 如[^aeiou]匹配除了aeiou这几个字母以外的任意字符
\ 在非特殊字符之前的反斜杠表示下一个字符是特殊的,不能从字面上解释。反斜杠也可以将其后的特殊字符,转义为字面量。使用 new RegExp("pattern")的时候不要忘记将 \ 进行转义,因为 \ 在字符串里面也是一个转义字符。

此外,对应还有\B \W \S \D,都匹配跟上面小写的意思相反

正则表达式里的单词是什么意思吧:就是不少于一个的连续的\w。

“(”和“)”也是元字符,需要时也是要使用转义的。

规则 描述
(x) 使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。
(?:x) 匹配 'x’但是不记住匹配项。这种叫作非捕获括号,不给此分组分配组号
(?x) 匹配x,并捕获文本到名称为name的组里,也可以写成 (?'name’x)

这里详细说说关于 (x)

默认情况下,每个分组会自动拥有一个组号,规则是:分组0对应整个正则表达式实际上组号分配过程是要从左向右扫描两遍的:第一遍只给未命名组分配,第二遍只给命名组分配--因此所有命名组的组号都大于未命名的组号

可以使用(?:exp)这样的语法来剥夺一个分组对组号分配的参与权。

后向引用用于重复搜索前面某个分组匹配的文本。
例如,\1代表分组1匹配的文本。

注意,这个不适合这样使用([…]),不适合包括在方括号里,这样的必须后面出现的跟第一次出现的匹配类型一致。
例如,/^([a-z\d])\1$/,可以是字母也可数字,但是第一次出现的数字的话,后面必须也是数字这个表达式才会正确用。

这个例子去运行一下就知道应用场景和意义了:'2018-09-87'.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/)

零宽断言

规则 描述
(?=x) 匹配x前面的位置,断言自身出现的位置的后面能匹配表达式x比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分)。 如查找I’m singing while you’re dancing.时,它会匹配sing和danc。 注意,这里的\w是必须的,因为匹配的就是这个东西,只是这个东西匹配出来的前提条件是后面接ing。
(?<=x) 匹配x后面的位置,它断言自身出现的位置的前面能匹配表达式x。 比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部 分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
(?!x) 匹配后面跟的不是x的位置,断言此位置的后面不能匹配表达式x。 例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字
(?<!x) 匹配前面不是x的位置,断言此位置的前面不能匹配表达式x。

这里有兼容性问题,有些浏览器只支持正向的零宽断言即(?=exp)和(?!exp),不支持负向零宽断言

贪婪与懒惰

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。

以这个表达式为例:a.*b,它将会匹配最长的以 a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。

有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。
这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。

a.*?b匹配最短的,以a开始,以b结 束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?

简单地说,因为正则表达式有另 一条规则,比懒惰/贪婪规则的优先级更高:** 最先开始的匹配拥有最高的优先权。**
懒惰模式适用于 * ? + {} 后面;

还有一个很好例子说明懒惰模式的用处,'{{f}},fas{{fsfsf}}a{{fsa}}'.match(/{{.+?}}/g)。 这个就能把一个字符串里所有{{}}的最小单位给筛选出来,可以去控制台里输出看看

怎么用?

被用于 RegExp 的 exec 和 test 方法, 以及 String 的 match、replace、search 和 split 方法。

exec()

语法
regexObj.exec(str)
返回值
如果匹配成功,exec()方法返回一个数组,并更新正则表达式对象的属性。返回的数组将完全匹配成功的文本作为第一项,将正则括号里匹配成功(即括号捕获)的作为数组填充到后面。
如果匹配失败,exec() 方法返回 null。

test()

语法
regexObj.test(str)
返回值
如果正则表达式与指定的字符串匹配,返回true;否则false。

search()

语法
str.search(regexp)
参数regexp,一个正则表达式(regular expression)对象。如果传入一个非正则表达式对象,则会使用 new RegExp(obj)隐式地将其转换为正则表达式对象。
返回值
如果匹配成功,则search()返回正则表达式在字符串中首次匹配项的索引。否则,返回 -1。

match()

语法
str.match(regexp);
参数regexp,一个正则表达式对象。如果传入一个非正则表达式对象,则会隐式地使用 new RegExp(obj) 将其转换为一个RegExp。如果你未提供任何参数,直接使用 match() ,那么你会得到一个包含空字符串的 Array :[""] 。
返回值
一个包含了整个匹配结果以及任何括号捕获的匹配结果的 Array ;如果没有匹配项,则返回 null 。
描述
如果正则表达式没有 g 标志,则str.match()会返回和 RegExp.exec()相同的结果。
相比有g,返回的Array拥有一个额外的input属性,该属性包含被解析的原始字符串。另外,还拥有一个index属性,该属性表示匹配结果在原字符串中的索引(以0开始)。

如果正则表达式包含 g 标志,则该方法返回一个 Array ,它包含所有匹配的子字符串而不是匹配对象。捕获组不会被返回(即不返回index属性和input属性)。如果没有匹配到,则返回 null 。

注意:只有用match方法才能体现g的意义

最后

如果你有正则匹配问题,欢迎咨询,尽量为你解答。

喜欢请点赞~转载注明出处谢谢~写文章不易

首发地----> 戳me

猜你喜欢

转载自blog.csdn.net/weixin_44244857/article/details/85232902