這個例子出自《精通正規表示式》,做一下筆記幫助理解和記憶。
最簡單的case就是考慮包含一對引號,那麼寫出來的表示式應該是這樣的:
".*"
但是這個未免太簡單了吧,會有啥問題呢?假如輸入的字串長這樣結果就會出問題拉。see...
input string: "hello" and "world"
regex: ".*"
match: "hello" and "world"
為什麼會全部匹配到呢?這是因為 * 是乙個greedy(匹配優先)的量詞,我覺得英文的意思更容易幫助我們理解。這意味著它會首先會'貪婪'得把所有的字元匹配完,匹配到最後乙個字元發現沒有字元可以匹配了,於是開始匹配下乙個引號,它會首先回朔到最後乙個引號前,然後開始匹配引號匹配引號,發現可以匹配,然後就完成了。這就是為啥整個字串都被匹配了。
既然是因為greedy的量詞導致的這個問題,那我們將其給成lazy(忽略優先)的量詞 ----- *? 。當乙個量詞是忽略優先的話,那在匹配的時候,引擎會選擇忽略這個忽略優先量詞修飾的字元去匹配下乙個字元,如果匹配則繼續,如果不匹配則返回來匹配這個忽略優先量詞修飾的字元。
看一下這個例子,將表示式稍作修改,匹配結果就變鳥。
input string: "hello" and "world"
regex: ".*?"
match-1: "hello"
match-2: "world"
好了,似乎這個版本已經圓滿完成我們的任務啦。
那我們將需求繼續變化一下,在程式的世界裡有一種東西叫做轉移字元,比如有個字串長這樣子\"hello, world!\"+\"
。 直接上最終正規表示式。
input string: \"hello, world!\"+\"
regex: "(\\.|[^\\"])*"
match-1: no match
正規表示式中關鍵的是這個(\\.|[^\\"])
,這個括號在正規表示式裡是起到乙個多選結構的作用,表示匹配括號內任意乙個子表示式即匹配。這個括號裡面由兩部分,第一部分是\\.
,第二部分是[^\\"]
。
\\.
能夠匹配任何的轉義字元,嚴格來說是匹配任意\以及其後面的字元,即使它們不是真正的轉義字元。
這個輸入字串最後乙個引號是轉移的引號,所以這個正規表示式沒有匹配到任何的結果。這個結果是對的,這個功勞就要歸結到這個[^\\"]
,它的意思是匹配非\"的任意字元。當引擎匹配到字串最後發現"
還未匹配,於是進行回溯,回溯到▴那個位置\"hello, world!\"+ ▴ \"
。引擎會嘗試去匹配[^\\"]
,發現匹配失敗,於是失敗!
假如我們將[^\\"]
換成[^"]
,那麼在剛才那個位置的時候,[^"]
就會匹配\
字元,然後\
之後的"
會被外層的引號匹配,於是它的結果就是被匹配了。這顯然是很奇怪的,當然如果你想要這麼匹配也可以。
還有一種方式是利用正規表示式裡面的固化分組(atomic grouping)或者占有優先量詞(possessive)。固化分組:"(?>(\\.|[^"])*)
,占有優先量詞:"(\\.|[^"])*+"
。在固化分組或者占有優先量詞的匹配過程中,在固化分組內或者占有優先量詞修飾的組內,如果乙個字元已經被匹配那麼之前的狀態將會被捨棄,就防止它進行回溯。
在這個例子中,\"hello, world!\"+\"
,當匹配到這個位置的時候(\"hello, world!\"+\" ▴
)發現沒有辦法繼續匹配下去了,引擎會選擇直接匹配失敗,而不是回溯到之前的備用狀態進行新的匹配。
例子雖然簡單,但是出現了正規表示式中很多關鍵的概念,預知詳情,請閱讀《精通正規表示式》
本文純屬個人讀書筆記,如有錯誤概不負責喲~~~
《精通正規表示式》筆記
1.多選結構 mm gg 表示匹配 mm 或 gg 2.忽略大小寫 s source dest i 搜尋source,將其替換為dest,此處的i只對source起作用,而不會作用於dest。3.單詞分界符 用來匹配單詞的開始 用來匹配單詞的結束 比如 cat 匹配以 cat 結尾的單詞,如scat...
精通正規表示式
我只看了前面兩三章 這書的核心是4 5 6章 精通正規表示式 這本書的第四章和第六章比較值得看 1.多選結構 mm gg 表示匹配 mm 或 gg 2.忽略大小寫 s source dest i 搜尋source,將其替換為dest,此處的i只對source起作用,而不會作用於dest。3.單詞分界...
精通正規表示式 1 正規表示式入門
1 能檢查多個檔案,挑出包含重複單詞的行,高亮標記每個重複單詞 使用標準ansi的轉義字元列 同時必須顯示這行文字來自哪個檔案。2 能跨行查詢,即使兩個單詞乙個在某行末尾而另乙個在下一行的開頭,也算重複單詞。3 能進行不區分大小寫的查詢,例如 the the.重複單詞之間可以出現任意數量的空白字元 ...