JavaRush /Java Blog /Random-TW /RegEx:掌握正規表示式的 20 個簡短步驟。第2部分
Artur
等級 40
Tallinn

RegEx:掌握正規表示式的 20 個簡短步驟。第2部分

在 Random-TW 群組發布
RegEx:掌握正規表示式的 20 個簡短步驟。第 1 部分 原文在這裡 在上一部分我們掌握了最簡單的正規表示式,並且已經學到了一些東西。在這一部分中,我們將研究稍微複雜的設計,但相信我,它不會像看起來那麼困難。 RegEx:掌握正規表示式的 20 個簡短步驟。 第 2 - 1 部分那麼就讓我們繼續吧!

第 8 步:星號*和加號+

RegEx:掌握正規表示式的 20 個簡短步驟。 第 2 - 2 部分到目前為止,我們或多或少只能匹配給定長度的字串。但在最近的問題中,我們已經接近了迄今為止我們所看到的符號的極限。例如,假設我們不限於 3 字元 Java 標識符,而是可以具有任意長度的標識符。在上一個範例中可能有效的解決方案在以下範例中將無法運作:
模式:[a-zA-Z_$]\w\w
字串:   __e $12 3 3.2 fo Bar r a23 mm ab x
符合:^^^ ^^^ ^^^ ^^^  
筆記當標識符有效但長度超過 3 個字元時,僅匹配前三個字元。當標識符有效,但包含少於 3 個字元時,正規表示式根本找不到它!問題是括號表達式與[]一個字元完全匹配,就像\w. 這意味著上述正規表示式中的任何符合項目都必須恰好是三個字元長。所以它的效果並沒有我們所希望的那麼好。*特殊字元和可以在這裡提供幫助+。這些修飾符可以添加到任何表達式的右側,以多次匹配該表達式。Kleene Star(或「星號」)*將指示前一個標記必須符合任意次數,包括零次。加號+表示您需要搜尋一次或多次。因此,前面的表達式+是強制性的(至少一次),而前面的表達式*是可選的,但當它出現時,它可以出現任意多次。現在,有了這些知識,我們可以修正上面的正規表示式:
模式:[a-zA-Z_$]\w*
字串:   __e $123 3.2 fo Barr a23mm ab x
匹配:^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ ^ 
範例)現在我們匹配任意長度的有效標識符!答對了!+但是如果我們使用 ?而不是?會發生什麼事*
模式:[a-zA-Z_$]\w+
字串:   __e $123 3.2 fo Barr a23mm ab x
配對:^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ 
)我們錯過了最後一場比賽,х。這是因為它需要+至少匹配一個字符,但是由於[]前面的括號表達式\w+已經“吃掉”了該字符x,所以沒有更多的可用字符,因此匹配失敗。我們什麼時候可以使用+?當我們需要找到至少一個匹配項,但給定表達式必須匹配多少次並不重要。例如,如果我們想找出任何包含小數點的數字:
模式:\d*\.\d+
字串:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012
相符:^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
筆記透過將小數點左邊的數字設為可選,我們能夠找到 0.011 和 0.2。為此,我們需要將一位小數點與 精確匹配\.,並將小數點右側至少一位數字與 匹配\d+。上面的正規表示式不會符合像這樣的數字3.,因為我們需要小數點右邊至少一位數字才能符合。

像往常一樣,讓我們解決幾個簡單的問題:

找出下面段落中的所有英語單字。
圖案:
字串:33是 6,但4加 3 是7
符合:    ^^^^ ^^ ^^^ ^^^ ^^^^ ^^^^^ ^^ 
解決方案)在下面的列表中找到所有檔案大小符號。檔案大小將由一個數字(帶或不帶小數點)後跟KBMB或組成: GBTB
圖案:
字串:   11TB 13 14.4MB 22HB 9.9GB TB 0KB
符合:^^^^ ^^^^^^ ^^^^^ ^^^  
解決方案

第9步:「可選」問號?

RegEx:掌握正規表示式的 20 個簡短步驟。 第 2 - 3 部分您已經編寫了正規表示式來解決最後一個問題嗎?有效嗎?現在嘗試在這裡應用它:
圖案:
字串:1..3KB 5...GB ..6TB
火柴:  
顯然,這些指定都不是有效的檔案大小,因此好的正規表示式不應與它們中的任何一個相符。我為解決最後一個問題而編寫的解決方案與它們全部匹配,至少部分匹配:
模式:\d+\.*\d*[KMGT]B
字串:   1..3KB  5...GB .. 6TB
符合:^^^^^^ ^^^^^^ ^^^ 
)那麼問題出在哪裡呢?事實上,如果有一位小數點的話,我們只需要找到一位小數點。但*它允許任意數量的匹配,包括零。有沒有辦法只匹配零次或一次?但不超過一次嗎?當然有。「可選」?是一個修飾符,匹配零個或一個前面的字符,但不能再匹配:
模式:\d+\.?\d*[KMGT]B
字串:1.. 3KB 5...GB .. 6TB
符合:     ^^^ ^^^ 
範例)我們在這裡更接近解決方案,但這並不是我們所需要的。稍後我們將透過幾個步驟了解如何解決此問題。

同時,讓我們解決這個問題:

在某些程式語言(例如 Java)中,某些整數和浮點(點)數字可能會後跟l/Lf/F來指示它們應該(分別)被視為 long/float,而不是常規的 int/double。在下面的行中找到所有有效的“長”數字:
圖案:
字串:   13L long 2l 19 L lL 0
匹配:^^^ ^^ ^^ ^ 
解決方案

第10步:「或」號|

RegEx:掌握正規表示式的 20 個簡短步驟。 第 2 - 4 部分在步驟 8 中,我們在尋找不同類型的浮點數時遇到了一些困難:
模式:\d*\.\d+
字串:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012
相符:^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
上面的模式匹配帶有小數點且小數點右側至少一位數字的數字。但是如果我們還想匹配像這樣的字串怎麼辦0.?(小數點右邊沒有數字。)我們可以寫出如下正規表示式:
模式:\d*\.\d*
字串:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. . 
符合:^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ ^ 
範例)這匹配0.,但它也匹配單一點.,如上所示。實際上我們想要匹配的是兩個不同的字串類別:
  1. 小數點右側至少一位數字
  2. 小數點左邊至少有一位數字的數字
讓我們寫出以下兩個相互獨立的正規表示式:
模式:\d*\.\d+
字串:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
符合:^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
模式:\d+\.\d*
字串:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. .
符合:^^^^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ 
我們發現在這些情況下,引擎都沒有找到子字串4256或。.為了獲得所需的結果,我們將這些正規表示式組合起來不會有什麼壞處。我們怎樣才能做到這一點?“or”符號|允許我們在正規表示式中一次指定多個可能的匹配序列。正如[]“或”符號允許我們指定替代的單一字元一樣,|我們也可以指定替代的多字元表達式。例如,如果我們想查找“dog”或“cat”,我們可以這樣寫:
模式:\w\w\w
字串:  顯然是比更好的寵物
符合:^^^^^^^^^ ^^^ ^^^^^^ ^^^ ^^^ ^^^ 
範例)...但這符合「word」類別的所有三重字元序列。但是“dog”和“cat”甚至沒有共同的字母,所以方括號在這裡對我們沒有幫助。這是我們可以使用的最簡單的正規表示式,它既匹配又僅匹配這兩個單字:
模式:dog|cat
字串:顯然,狗是比更好的寵物。
配對:               ^^^ ^^^ 
範例)正規表示式引擎首先嘗試匹配字元左側的整個序列|,但如果失敗,則它會嘗試匹配字元右側的序列|。多個字元|也可以連結起來以匹配兩個以上的替代序列:
模式:dog|cat|pet
字串:顯然,是比更好的寵物
配對:               ^^^ ^^^ ^^^ 

現在讓我們解決另外幾個問題以更好地理解此步驟:

使用符號|來修正上面的小數正規表示式以產生以下結果:
圖案:
字串:   0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0 ..
符合:^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ 
解決方案)使用符號|、字元類別、「可選」?等創建一個同時匹配整數和浮點(點)數的單一正則表達式,如上一步末尾的問題中所討論的(這個問題有點更複雜,是的;))
圖案:
字串:   42L 12 x 3.4f 6l 3.3 0F LF .2F 0。
符合:^^^ ^^ ^^^^ ^^ ^^^ ^^ ^^^ ^^  
解答20個小步驟掌握正規表示式。第 3 部分 RegEx:掌握正規表示式的 20 個簡短步驟。第 4 部分
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION