正则表达式(长期更新)

1.  *、+、?

*:匹配前面的子表达式零次或多次

+:......一次或多次

?:......零次或一次,或指明一个非贪婪限定符

2. DFA与NFA

正则表达式引擎分为两类,一类叫做DFA(确定性有穷自动机),另一类叫NFA(非确定性有穷自动机)

两类引擎正常工作都需要有一个正则表达式和一个文本串,两类引擎的主要区别是“捏哪个在手里去吃另一个”。

DFA会手握字符串去比较正则表达式。正则表达式作为“输入”,每看到一个子正则式,就将可能的匹配串全标注出来,然后再看正则式的下一个部分,根据新的匹配结果更新标注。

NFA则会手握正则表达式去对比文本。文本字符串作为“输入”,每吃掉一个字符,就把它跟正则式比较,如果匹配,就记:“某年某月某日在某处匹配上了”,然后继续“吃”。一旦匹配不上,就把刚吃的这个字符吐出来,一个个的吐,直到回到上次匹配处。

两种引擎机制上的不同带来主要影响:

DFA对于文本串里的每一个字符只需扫描一次,比较快,但特性少;

NFA要反复去吃字符、吐字符,速度慢,但是特性丰富,所以反而应用广泛。

当今主要的正则表达式引擎,如Perl、Ruby、Python的re模块、Java和.NET的regex库,均基于NFA。

3. 贪婪与非贪婪

贪婪与非贪婪模式影响的是被量词修饰的子表达式的匹配行为,贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配.

而非贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配。

注:非贪婪模式只被部分NFA引擎支持。

例子:

源字符串:aa<div>test1</div>bb<div>test2</div>cc 

正则表达式一:<div>.*</div> 

匹配结果一:<div>test1</div>bb<div>test2</div> 

正则表达式二:<div>.*?</div> 

匹配结果二:<div>test1</div>(这里指的是一次匹配结果,所以没包括<div>test2</div>) 

根据上面的例子,从匹配行为上分析一下,什是贪婪与非贪婪模式。 

正则表达式一采用的是贪婪模式,在匹配到第一个“</div>”时已经可以使整个表达式匹配成功,但是由于采用的是贪婪模式,所以仍然要向右尝试匹配,查看是否还有更长的可以成功匹配的子串,匹配到第二个“</div>”后,向右再没有可以成功匹配的子串,匹配结束,匹配结果为“<div>test1</div>bb<div>test2</div>”。当然,实际的匹配过程并不是这样的,后面的匹配原理会详细介绍。 

仅从应用角度分析,可以这样认为,贪婪模式,就是在整个表达式匹配成功的前提下,尽可能多的匹配,也就是所谓的“贪婪”,通俗点讲,就是看到想要的,有多少就捡多少,除非再也没有想要的了。 

正则表达式二采用的是非贪婪模式,在匹配到第一个“</div>”时使整个表达式匹配成功,由于采用的是非贪婪模式,所以结束匹配,不再向右尝试,匹配结果为“<div>test1</div>”。 

仅从应用角度分析,可以这样认为,非贪婪模式,就是在整个表达式匹配成功的前提下,尽可能少的匹配,也就是所谓的“非贪婪”,通俗点讲,就是找到一个想要的捡起来就行了,至于还有没有没捡的就不管了。 

猜你喜欢

转载自blog.csdn.net/liu123641191/article/details/80683304