JS正则表达式一条龙讲解(从原理和语法到JS正则(3)

正则2的.*?为非贪婪匹配,尽可能少地匹配,所以匹配'233}'的每一个字符的时候,都是尝试不匹配,但是一但控制权交还给最后的}就发现出问题了,赶紧回溯乖乖匹配,于是每一个字符都如此,最终匹配成功。

云里雾里?这就对了!可以移步去下面推荐的博客看看:

想详细了解贪婪和非贪婪匹配原理以及获取更多正则相关原理,除了看书之外,推荐去一个CSDN的博客 雁过无痕-博客频道 - CSDN.NET ,讲解得很详细和透彻

二、语法一览

正则的语法相信许多人已经看过deerchao写的30分钟入门教程,我也是从那篇文字中入门的,deerchao从语法逻辑的角度以.NET正则的标准来讲述了正则语法,而我想重新组织一遍,以便于应用的角度、以JS为宿主语言来重新梳理一遍语法,这将便于我们把语言描述翻译成正则表达式。

下面这张一览图(可能需要放大),整理了常用的正则语法,并且将JS不支持的语法特性以红色标注出来了(正文将不会描述这些不支持的特性),语法部分的详细描述也将根据下面的图,从上到下,从左到右的顺序来梳理,尽量不啰嗦。

常用正则语法一览横版有标题.png

1. 要用某类常见字符——简单元字符

为什么这里要加简单2个字,因为在正则中,\d、\w这样的叫元字符,而{n,m}、(?!exp)这样的也叫元字符,所以元字符是在正则中有特定意义的标识,而这一小节讲的是简单的一些元字符。

.匹配除了换行符以外的任意字符,也即是[^\n],如果要包含任意字符,可使用(.|\n)

\w匹配任意字母、数字或者下划线,等价于[a-zA-Z0-9_],在deerchao的文中还指出可匹配汉字,但是\w在JS中是不能匹配汉字的

\s匹配任意空白符,包含换页符\f、换行符\n、回车符\r、水平制表符\t、垂直制表符\v

\d匹配数字

\un匹配n,这里的n是一个有4个十六进制数字表示的Unicode字符,比如\u597d表示中文字符“好”,那么超过\uffff编号的字符怎么表示呢?ES6的u修饰符会帮你。

2. 要表示出现次数(重复)——限定符

a*表示字符a连续出现次数 >= 0 次

a+表示字符a连续出现次数 >= 1 次

a?表示字符a出现次数 0 或 1 次

a{5}表示字符a连续出现次数 5 次

a{5,}表示字符a连续出现次数 >= 5次

a{5,10}表示字符a连续出现次数为 5到10次 ,包括5和10

3. 匹配位置——定位符和零宽断言

匹配某个位置的表达式都是零宽的,这是主要包含两部分,一是定位符,匹配一个特定位置,二是零宽断言,匹配一个要满足某要求的位置。

定位符有以下几个常用的:

\b匹配单词边界位置,准确的描述是它匹配一个位置,这个位置前后不全是\w能描述的字符,所以像\u597d\babc是可以匹配“好abc”的。

^匹配字符串开始位置,也就是位置0,如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置

$匹配字符串结束位置,如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置

零宽断言(JS支持的)有以下两个:

(?=exp)匹配一个位置,这个位置的右边能匹配表达式exp,注意这个表达式仅仅匹配一个位置,只是它对于这个位置的右边有要求,而右边的东西是不会被放进结果的,比如用read(?=ing)去匹配“reading”,结果是“read”,而“ing”是不会放进结果的

(?!exp)匹配一个位置,这个位置的右边不能匹配表达式exp

4. 想表达“或”的意思——字符簇和分歧

我们经常会表达“或”的含义,比如这几个字符中的任意一个都行,再比如匹配5个数字或者5个字母都行等等需求。

字符簇可用来表达字符级别的“或”语义,表示的是方括号中的字符任选一:

[abc]表示a、b、c这3个字符中的任意一个,如果字母或者数字是连续的,那么可以用-连起来表示,[b-f]代表从b到f这么多字符中任选一个

[(ab)(cd)]并不会用来匹配字符串“ab”或“cd”,而是匹配a、b、c、d、(、)这6个字符中的任一个,也就是想表达“匹配字符串ab或者cd”这样的需求不能这么做,要这么写ab|cd。但这里要匹配圆括号本身,讲道理是要反斜杠转义的,但是在方括号中,圆括号被当成普通字符看待,即便如此,仍然建议显式地转义

分歧用来表达表达式级别的“或”语义,表示的是匹配|左右任一表达就可:

ab|cd会匹配字符串“ab”或者“cd”

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjsgjw.html