问题描述
本文链接:http://www.hcoding.com/?p=130
初学正则表达式的时候都有一个疑问,例如:需要匹配串 " _abc_123_ " 中 第一对"_"之间的字符,刚开始学习正则表达式的时候会写成 " /_\w*_/ ",匹配的结果就是" abc_123 " 而不是" abc "了;大神说加上一个问号," /_\w*?_/ ",这时候匹配的结果就是" abc "。
我们知道' ? '单独使用的时候表示:重复零次或一次,而当' ? '出现在重复限定符后面的,起的作用就是懒惰匹配,也就是匹配尽可能少的字符。懒惰限定符说明:
*?:重复任意次, 但尽可能少重复 +?:重复1次或更多次, 但尽可能少重复 ??:重复0次或1次, 但尽可能少重复 {n,m}?:重复n到m次, 但尽可能少重复 {n,}?:重复n次以上, 但尽可能少重复对的,[尽可能少重复],这就是对懒惰匹配的粗暴直白的解说。
那么怎么理解[尽可能少重复]呢?我们可以从正则表达式的忽略优先量词来解释了。
忽略优先量词量词"*?"、"+?"、"??"、"{n,m}?"、"{n,}?"都属于忽略优先量词,忽略优先量词使用的是在?、+、*、{}后面添加?组成的,忽略优先在匹配的时候首先会尝试忽略,如果失败后回溯才会选择尝试。比如`ab??`匹配[abb]会得到‘a’而不是[ab]。当引擎匹配成功a后,由于是忽略优先,引擎首先选择不匹配b,继续查看表达式,发现表达式结束了,那么引擎就直接上报匹配成功。具体我们通过下面的例子一步一步说明忽略优先量词工作原理。
例子还是上面的例子,用" /_\w*?_/ "匹配" _abc_123_ " 中 第一对"_"之间的字符。
开始匹配第一个'_'之后,‘\w*?’首先决定不需要匹配任何字符,因为它是忽略优先量词,这时候就拿表达式'/_\w*? _ /'中的第二个' _ '('\w*?'后面的'_')和目标串'_ a bc_123_'中的'a'匹配,匹配失败,这时候才会拿'\w*?'去尝试未匹配的分支(使用\w匹配a,尝试匹配a成功)
下一步,是尝试匹配,还是忽略呢?因为'\w*?'是忽略优先量词,会选择忽略,那么就是重复上一步,'_'匹配b失败,'\w*?'去尝试未匹配的分支ab,以上步骤总共重复了3次后(直到表达式'\w*?'后面的'_'和目标串第二个'_'匹配),最终匹配出'abc'。
过程(开始匹配第一个'_'之后):
表达式/_\w*? _ /'中的第二个' _ '和目标串'_ a bc_123_'中的'a'匹配,匹配失败,'\w*?'尝试匹配目标串'_ a bc_123_'中的'a',匹配成功。 表达式/_\w*? _ /'中的第二个' _ '和目标串'_a b c_123_'中的'b'匹配,匹配失败,'\w*?'尝试匹配目标串'_ ab c_123_'中的'ab',匹配成功。 表达式/_\w*? _ /'中的第二个' _ '和目标串'_ab c _123_'中的'c'匹配,匹配失败,'\w*?'尝试匹配目标串'_ abc _123_'中的'abc',匹配成功。 表达式/_\w*? _ /'中的第二个' _ '和目标串'_abc _ 123_'中的'_'匹配,匹配成功,匹配结束。结果为abc。以上是阅读《精通正则表达式》关于忽略优先量词一节的想法,如有不对虚心接受各位的指教,谢谢!
本文链接:http://www.hcoding.com/?p=130
原创文章,转载请注明:JC&hcoding.com