首頁  >  文章  >  後端開發  >  個人理解正規表示式-懶惰匹配

個人理解正規表示式-懶惰匹配

WBOY
WBOY原創
2016-08-08 09:33:021011瀏覽

問題描述

本文連結: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*?'後面的'_')和目標串'_abc_123_'中的'a'匹配,匹配失敗,這時候才會拿'w*?'去嘗試未匹配的分支(使用w匹配a,嘗試匹配a成功)

下一步,是嘗試匹配,還是忽略呢?因為'w*?'是忽略優先量詞,會選擇忽略,那麼就是重複上一步,'_'匹配b失敗,'w*?'去嘗試未匹配的分支ab,以上步驟總共重複了3次後(直到表達式'w*?'後面的'_'和目標字串第二個'_'匹配),最終匹配出'abc'。

過程(開始匹配第一個'_'之後):

  • 表達式/_w*?_/'中的第二個'_'和目標串'_abc_123_'中的'a'匹配,匹配失敗,'w*?'嘗試匹配目標串'_abc_123_'中的'a',匹配成功。
  • 表達式/_w*?_/'中的第二個'_'和目標字串'_abc_123_'中的'b'匹配,匹配失敗,'w*?'嘗試匹配目標串'_abc_123_'中的'ab',匹配成功。
  • 表達式/_w*?_/'中的第二個'_'和目標串'_abc_123_'中的'c'匹配,匹配失敗,'w*?'嘗試匹配目標串'_abc_123_'中的'abc',匹配成功。
  • 表達式/_w*?_/'中的第二個'_'和目標串'_abc_123_'中的'_'匹配,匹配成功,匹配結束。結果為abc。

以上是閱讀《精通正規表示式》關於忽略優先量詞一節的想法,如有不對虛心接受各位的指教,謝謝!

本文連結:http://www.hcoding.com/?p=130

原創文章,轉載請註明:JC&hcoding.com

以上就介紹了個人理解正規表示式——懶惰匹配,包括了方面的內容,希望對PHP教程有興趣的朋友有所幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn