正则表达式贪婪和非贪婪模式的详细说明(概述)
1概述贪婪和非贪婪模式影响被量词修饰的子表达式的匹配行为。贪婪模式在整个表达式匹配成功的前提下匹配尽可能多,而非贪婪模式在整个表达式匹配成功的前提下匹配尽可能少。非贪婪模式仅受某些NFA引擎支持。属于贪婪模式的分类器,也称为匹配优先级分类器,包括:“{m,n}”、“{m,}”、“?”。“*”和“”。在某些使用NFA引擎的语言中在匹配优先级量词后添加。也就是说,它变成了属于非贪婪模式的量词,也叫忽略优先级量词,包括:“{m,n}?”、“{m,}?”、"?"、"*?"还有“?”。从正则语法来看,匹配优先量词修饰的子表达式使用贪婪模式,如“(表达式)”;通过忽略优先量词修改的子表达式使用非贪婪模式,例如“(表达式)?”。对于贪婪模式,各种文档的名称基本相同,但对于非贪婪模式,有的称为懒模式或懒模式,有的称为勉强模式。其实叫什么并不重要,只要掌握了原理和用法,就可以自由使用。个人习惯于使用贪婪和非贪婪这两个术语,所以本文将使用这个术语进行介绍。2匹配贪婪和非贪婪模式的原则我们可以从应用和原理两个方面来理解贪婪和非贪婪模式,但是如果我们真的想掌握它们,就应该从匹配的原则来理解它们。一、从应用角度,回答“什么是贪婪和非贪婪模式?”2.1从应用的角度分析贪婪和非贪婪模式2.1.1什么是贪婪和非贪婪模式?首先看一个例子:source string:aadiv test1/divbdiv test2/div cc正则表达式1: div。*/div匹配结果1: divtest1/divbbdivtest2/div正则表达式2: div。*?/div匹配结果2: divtest1/div(这里指的是主匹配结果,所以不包括divtest2/div)根据上面的例子,分析匹配行为,什么是贪婪和非贪婪模式?第一个正则表达式采用贪婪模式,当第一个“/div”匹配时,可以使整个表达式匹配成功。但是,由于贪婪模式,仍然需要尝试向右匹配,看看是否有更长的子字符串可以成功匹配。第二个“/div”匹配后,右边没有可以成功匹配的子串,匹配结果为“divtest1/divbbdivtest2/”。当然实际的匹配过程并不是这样,匹配原理后面会详细介绍。从应用的角度来看,我们可以认为贪婪模式是在整个表达式匹配成功的前提下,匹配尽可能多的表达式,称为“贪婪”。一般来说,意思是想捡多少就捡多少,除非没有你想要的了。正则表达式2采用了非贪婪模式,使得第一个“/div”匹配时整个表达式匹配成功。由于采用非贪婪模式,匹配结束,匹配结果为“divtest1/div”。仅从应用的角度来看,我们可以认为非贪婪模式是在整个表达式匹配成功的前提下,尽量少匹配,也叫“非贪婪”。一般来说,就是找到自己想要的东西,捡起来,剩下什么都无所谓。2.1.2前提条件描述从上述应用角度分析贪婪和非贪婪模式时,一直提到的前提条件之一就是“整个表达式匹配成功”。为什么要强调这个前提?让我们看看下面的例子。正则表达式3: div。*/divbb匹配结果3: divtest1/divbb修改" "并且仍然匹配优先级量词“*”,所以这仍然是贪婪模式。前面的“div。*/div”仍然可以匹配到“div test1/divbbdivetest2/div”,但由于后面的“bb”不能匹配成功,那么“div test1/divbbdivetest2/div”。此时整个表达式的匹配结果为“divtest1/divbb”,匹配内容为“div”。*/div”是“divtest1/div”。
可以看出,贪婪模式确实在“整个表达式匹配成功”的前提下影响了子表达式的匹配行为。如果整个表达式匹配失败,贪婪模式只会影响匹配过程,其对匹配结果的影响无从谈起。非贪婪模式也存在同样的问题。请看下面的例子。正则表达式4: div。*?/divcc匹配结果4: divtest1/divbbdivtest2/divcc这里采用非贪婪模式,前面的“div。*?/div”在“divtest1/div”之前仍然匹配,后面的“cc”无法成功匹配,所以“div。*? "是必需的。/div”必须继续向右尝试匹配,直到匹配内容为“divtest1/divbbdivtest2/div”,那么后面的“cc”就可以成功匹配,整个表达式就可以成功匹配。匹配的内容是“divtest1/divbbdivtest2/divcc”,其中“div。*?/div“匹配”。
版权声明:正则表达式贪婪和非贪婪模式的详细说明(概述)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。