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

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

在 Random-TW 群組發布
這篇文章的原文在這裡。也許沒有太多的理論,我將在文章末尾提供一些關於正則表達式的更詳細材料的連結。但在我看來,如果有機會不僅可以臨時抱佛腳,而且還可以透過完成小任務來立即鞏固知識,那麼開始鑽研正規表示式這樣的主題會更有趣。 RegEx:掌握正規表示式的 20 個簡短步驟。 第 1 - 1 部分讓我們開始吧。通常,反對在程式設計中使用正規表示式(「RegEx」或簡稱「regex」)的人會引用 Jamie Zawinski 的以下引言: 「有些 人在遇到問題時會想,'我知道,我會使用正規表達式」「現在他們有兩個問題」。 事實上,使用正規表示式還沒有好壞之分。這本身不會增加問題,也不會解決任何問題。它只是一個工具。你如何使用它(正確或錯誤)決定了你會看到什麼結果。例如,如果您嘗試使用正規表示式來建立 HTML 解析器,那麼您很可能會遇到痛苦。但是,如果您只想從某些行中提取時間戳,那麼您可能會沒問題。為了讓您更輕鬆地掌握正規表示式,我整理了本課程,只需二十個簡短的步驟即可幫助您從頭開始掌握正規表示式。本教程主要關注正規表示式的基本概念,並僅在必要時深入研究更高級的主題。

第 1 步:為什麼要使用正規表示式

RegEx:掌握正規表示式的 20 個簡短步驟。 第 1 - 2 部分正規表示式用於使用指定的模式(pattern)在文字中搜尋匹配項。使用正規表示式,我們可以輕鬆簡單地從文字中提取單字,以及滿足特定條件的單一文字和元字元及其序列。以下是維基百科 對它們的介紹:正規表示式是一種基於元字元(通配符)的使用來搜尋和操作文字中子字串的正式語言。對於搜索,使用範例字串(英語模式,在俄語中通常稱為「模板」、「掩碼」),由符號和元符號組成並定義搜尋規則。為了操作文本,還指定了替換字串,該字串也可以包含特殊字元。 該模式可以像dog這句話中的單字一樣簡單:
敏捷的棕色狐狸跳過了懶狗。
這個正規表示式看起來像這樣:
……很容易,不是嗎?該模式也可以是包含該字母的任何單字o。尋找此類模式的正規表示式可能如下所示:
\哇* _
您可以在這裡嘗試這個正規表示式。)您會注意到,隨著「匹配」要求變得更加複雜,正規表示式也變得更加複雜。還有其他形式的符號用於指定字元組和匹配重複模式,我將在下面解釋。但是,一旦我們在某些​​文本中找到與模式的匹配,那麼我們可以用它做什麼呢?現代正規表示式引擎可讓您從包含的文字中提取字元或字元序列(子字串),或將其刪除,或將其替換為其他文字。一般來說,正規表示式用於解析和操作文字。例如,我們可以提取看起來像 IP 位址的子字串,然後嘗試驗證它們。或者我們可以提取姓名和電子郵件地址並將它們儲存在資料庫中。或使用正規表示式尋找電子郵件中的敏感資訊(例如護照號碼或電話號碼),並提醒使用者可能會將自己置於危險之中。正規表示式確實是一種易於學習但難以掌握的多功能工具: “正如演奏好一首音樂和創作音樂之間存在差異一樣,了解正則表達式和理解它們之間也存在差異。” - Jeffrey E. F. Friedl,《掌握正規表示式》

第 2 步:方括號[]

最容易理解的最簡單的正則表達式是那些簡單地在正則表達式模式和目標字串之間查找逐字匹配的正則表達式。例如,讓我們嘗試尋找一隻貓: RegEx:掌握正規表示式的 20 個簡短步驟。 第 1 - 3 部分
圖案:
字串:貓跑到車底下時被割傷。
配對:      ^^^
它在實踐中是如何運作的 - 請參閱此處注意! 此處提供的所有解決方案僅作為可能的解決方案。在正規表示式中,就像在一般程式設計中一樣,您可以用不同的方式解決相同的問題。 然而,除了嚴格的逐個字元比較之外,我們還可以使用方括號指定替代匹配:
模式:ca[rt]
字串:貓跑到車底下時被割傷。
配對:      ^^^ ^^^
它是如何工作的)左方括號和右方括號告訴正則表達式引擎它應該匹配任何指定的字符,但只能匹配一個。例如,上面的正規表示式不會找到cart整個單詞,只會找到其中的一部分:
模式:ca[rt]
字串:貓跑到車底下時被割傷。
配對:      ^^^ ^^^
它是如何運作的)當您使用方括號時,您告訴正規表示式引擎僅符合方括號內包含的字元之一。引擎先找到字符c,然後找到字符a,但如果下一個字符不是rt,則這不是完全匹配。如果它找到ca,然後是r,或者t,它就會停止。它不會嘗試匹配更多字符,因為方括號表示只需要匹配所包含的字符之一。當它找到時ca,它會r在單字next 中查找cart,然後停止,因為它已經找到了該序列的匹配項car

培訓目標:

寫一個正規表示式,與這段不可翻譯的當地方言雙關語摘錄 had中的所有 10 個模式相符:Had
圖案:
字串:Jim,其中 Bill 有“had”,有“had had”「曾經」是正確的。
配對:                  ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^
請參閱此處可能的解決方案)以下句子中的所有動物名稱怎麼樣?
圖案:
字串:一隻蝙蝠、一隻貓一隻老鼠走進了一家酒吧…
配對:    ^^^ ^^^ ^^^
可能的解決方案)或更簡單:找到單字baror bat
圖案:
字串:一隻蝙蝠、一隻貓一隻老鼠走進了一家酒吧…
配對:    ^^^ ^^^
可能的解決方案)現在我們已經學會如何編寫或多或少複雜的正則表達式,並且我們只處於第2步!讓我們繼續吧!

第 3 步:轉義序列

RegEx:掌握正規表示式的 20 個簡短步驟。 第 1 - 4 部分在上一步中,我們了解了方括號[]以及它們如何幫助我們使用正規表示式引擎找到替代匹配項。但是,如果我們想查找左方括號和右方括號本身形式的匹配項呢[]?當我們想要找出單字 的逐個字元匹配時cat,我們向正規表示式引擎提供了這個字元序列 ( cat)。[]讓我們試著以同樣的方式 找到方括號:
模式:[]
字串:你不能使用正規表示式來匹配[]!你會後悔的!
火柴: 
讓我們看看發生了什麼)但是,有些東西不起作用...這是因為方括號字符充當特殊的正則表達式引擎字符,通常用於指示其他內容,而不是匹配它們本身的文字模式。正如我們在步驟 2 中所記得的那樣,它們用於查找替代匹配項,以便正規表示式引擎可以匹配它們之間包含的任何字元。如果它們之間不放置任何字符,則可能會導致錯誤。為了匹配這些特殊字符,我們必須在它們前面加上反斜線字符來轉義它們\。反斜線(或反斜線)是另一個特殊字符,它告訴正則表達式引擎按字面意思找到下一個字符,而不是將其用作元字符。正規表示式引擎只會找出字元[]字面意思,如果它們前面都有反斜線:
圖案:\[\]
字串:您無法使用正規表示式匹配 []!你會後悔的!
匹配:                  ^^ 
讓我們看看這次發生了什麼)好吧,如果我們想找到反斜線本身怎麼辦?答案很簡單。由於反斜線\也是特殊字符,因此也需要轉義。如何?反斜線!
圖案:\\
字串:C:\Users\Tanja\Pictures\Dogs
配對:    ^ ^ ^ ^
實踐中的相同範例)只有特殊字元前面才應該有反斜線。預設情況下,所有其他字元均按字面解釋。例如,正規表示式t僅符合t小寫字母:
圖案: t
字串:tttt
配對:^ ^ ^ ^
範例)但是,此序列的\t工作方式有所不同。這是一個用於搜尋製表符的範本:
模式:\t
字串:tttt
配對:   ^ ^ ^
範例)一些常見的轉義序列包括\n(UNIX 樣式換行符)和\r(用於 Windows 樣式換行符\r\n)。\r是「回車」字元和\n「換行」字符,這兩個字符都是在電傳打字機仍在廣泛使用時與 ASCII 標準一起定義的。 本教學稍後將介紹其他常見的轉義序列。

同時,讓我們用幾個簡單的謎題來強化材料:

嘗試編寫正規表示式來尋找...正規表示式;)結果應該是這樣的:
圖案:
字串:...將此正規表示式 ` \[\] ` 與正規表示式相符?
配對:                       ^^^^	
解答)你做到了嗎?做得好!現在嘗試建立一個正規表示式來搜尋轉義序列,如下所示:
圖案:
字串:` \r `、` \t ` 和 ` \n ` 都是正規表示式轉義序列。
匹配:   ^^ ^^ ^^
解決方案

第 4 步:使用點來尋找「任意」字符.

RegEx:掌握正規表示式的 20 個簡短步驟。 第 1 - 5 部分在編寫我們在上一步中看到的轉義序列匹配解決方案時,您可能想知道,“我可以匹配反斜杠字符,然後匹配它後面的任何其他字符嗎?”...當然可以!還有另一個特殊字元用於匹配(幾乎)任何字元 - 點(句號)字元。它的作用如下:
圖案:
string:對不起,戴夫。恐怕我做不到。
符合:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^	
範例)如果您只想匹配看起來像轉義序列的模式,您可以執行以下操作:
圖案:\\。
字串:嗨,沃爾瑪是我的孫子,他的名字是「\n\r\t」。
匹配:                                             ^^ ^^ ^^	
範例)並且,與所有特殊字元一樣,如果要匹配文字.,則需要在其前面添加一個字元\
圖案:\。
字串:戰爭即和平自由就是奴役無知就是力量
配對:            ^ ^ ^

第 5 步:字元範圍

RegEx:掌握正規表示式的 20 個簡短步驟。 第 1 - 6 部分如果您不需要任何符號,而只想在文字中找到字母怎麼辦?還是數字?還是元音?按字元類別及其範圍進行搜尋將使我們能夠實現這一目標。
` \n `、` \r ` 和 ` \t `空白字符,` \。`、` \\ ` 和 ` \[ `不是
如果字元不在文字中建立可見標記,則它們 是「空白」 。 空格「 」是空格、換行符或製表符。假設我們想要找出僅代表上面段落中的空白字元 和 的轉義序列,而不是其他轉義\n序列\r\t我們怎樣才能做到這一點?
模式:\\[nrt]
字串:` \n `、` \r ` 和 ` \t `空白字符,` \. `、` \\ ` 和 ` \[ `不是。
匹配:   ^^ ^^ ^^	
範例)這可行,但不是一個非常優雅的解決方案。如果稍後我們需要匹配「換頁」字元的轉義序列怎麼辦\f?(此符號用於指示文字中的分頁符號。)
模式:\\[nrt]
字串:` \n`、` \r`、` \t`和 ` \f`空白字符,` \. `、` \\ ` 和 ` \[ `不是。
匹配:   ^^ ^^ ^^	
不起作用的解決方案)使用這種方法,我們需要在方括號中單獨列出我們想要匹配的每個小寫字母。一種更簡單的方法是使用字元範圍來匹配任何小寫字母:
模式:\\[az]字串
:` \n`、` \r`、` \t`和 ` \f`空白字符,` \. `、` \\ ` 和 ` \[ `不是。
匹配:   ^^ ^^ ^^ ^^	
這已經有效)考慮到上面的範例,字元範圍正如您所期望的那樣工作。將要配對的第一個和最後一個字母放在方括號內,中間使用連字號。例如,如果您只想尋找反斜線\ato中的一個字母的「群組」 m,您可以執行以下操作:
模式:\\[am]字串
:` \n`、` \r`、` \t`和 ` \f`空白字符,` \. `、` \\ ` 和 ` \[ `不是。
匹配:                         ^^	
範例)如果要匹配多個範圍,只需將它們首尾相連地放在方括號之間:
模式:\\[a-gq-z]
字串:` \n `、` \r `、` \t ` 和 ` \f `空白字符,` \. `、` \\ ` 和 ` \[ `不是。
匹配:         ^^ ^^ ^^	
範例)其他常見字元範圍包括:A-Z0-9

讓我們在實踐中嘗試並解決幾個問題:

十六進制數字可以包含數字0-9和字母A-F。當用於指定顏色時,十六進位代碼最多可以包含三個字元。建立正規表示式以在下面的清單中找到有效的十六進位代碼:
圖案:
字串:1H8 4E2 8FF 0P1 T8B 776 42B G12
符合:      ^^^ ^^^ ^^^ ^^^	
)使用字元範圍,建立一個正規表示式,該表達式將僅選擇y下面句子中的小寫子音(不是元音,包括 ):
圖案:
字串:商場非常。_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
符合:   ^ ^ ^^^ ^ ^^ ^ ^^ ^ ^ ^ ^^^ ^ ^ ^^^ ^ ^^	
解決方案

第 6 步:「not」、脫字號、抑揚符、脫字號...符號^

RegEx:掌握正規表示式的 20 個簡短步驟。 第 1 - 7 部分確實,這個符號有超過 9000 個名稱:)但是,為了簡單起見,也許我們會關注「not」。我對最後一個問題的解決方案有點長。「取得除元音之外的整個字母表」需要 17 個字元。當然,還有一種更簡單的方法可以做到這一點。「not」符號^允許我們指定不能模式中指定的字元和字元範圍相符的字元和字元範圍。上面最後一個問題的一個更簡單的解決方案是尋找不代表元音的字元:
模式:[ ^ aeiou ]字串
:  商場裡非常。_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
符合:^^ ^^ ^^^^ ^^^^ ^^ ^^^ ^ ^^ ^ ^^^^^^ ^ ^^^^^ ^^^ 	
範例)「not」符號^作為方括號內最左邊的字符,[]告訴正規表示式引擎匹配不在方括號內的一個(任何)字元。這意味著上面的正規表示式也符合句子開頭的所有空格、句號.、逗號,和大寫字母。T為了排除它們,我們也可以將它們放在方括號中:
模式[ ^ aeiou . , T ]字串 
:房間非常。_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
符合:   ^ ^ ^^^ ^ ^^ ^ ^^ ^ ^ ^ ^^^ ^ ^ ^^^ ^ ^^	
筆記在這種情況下,我們不需要用反斜線來轉義句點,就像我們之前在不使用方括號來尋找它時所做的那樣。方括號中的許多特殊字符按字面意思處理,包括左括號字符[,但不包括右括號]字符(你能猜出為什麼嗎?)。反斜線字元\也不按字面解釋。如果要\使用方括號匹配文字反斜杠,則必須透過在其前面添加以下反斜杠對其進行轉義\\。此行為的設計是為了使空白字元也可以放置在方括號中進行匹配:
模式:[\t]
字串:tttt
配對:   ^ ^ ^
範例)“not”符號^也可以與範圍一起使用。如果我只想捕獲字元a, b, c, x,yz,我可以這樣做:
模式:[abcxyz]
字串:   abc defghijklmnopqrstuvw xyz
符合:^^^ ^^^
範例)...或者,我可以指定我想要尋找不在d之間的任何字元w
模式:[^dw]
字串:   abc defghijklmnopqrstuvw xyz
符合:^^^ ^^^
)但是,當心與「不」^。人們很容易想到「好吧,我指定了[^ b-f],所以我應該在 後面得到一個小寫字母a或其他東西f。事實並非如此。這個正則表達式將匹配不在該範圍內的任何字符,包括字母、數字、標點符號和空格。
模式:[^dw]
字串:   abc defg h i , j - klmnopqrstuvw xyz
匹配:^^^ ^ ^ ^ ^ ^^^

升級任務:

使用方括號中的“not”符號^來匹配下面所有不以 結尾的單字y
圖案:
字串:daydog hog hay bog bay ray rub
符合:      ^^^ ^^^ ^^^ ^^^	
解決方案)使用範圍和「非」符號編寫正規表示式^來找出 1977 年到 1982 年(含)之間的所有年份:
圖案:
字串:1975 1976 1977 1978 1979 1980 1981 1982 1983 1984
配對:            ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
)寫一個正規表示式來找出所有不是「not」符號字元的字元^
圖案:
字串:   abc1 ^ 23*()
符合:^^^^ ^^^^^	
解決方案

第 7 步:字元類

字元類別甚至比字元範圍更簡單。不同的正規表示式引擎有不同的可用類,因此我在這裡只介紹主要的類別。(檢查您正在使用哪個版本的正則表達式,因為可能有更多版本- 或者它們可能與此處顯示的不同。)字元類的工作方式幾乎與範圍類似,但您無法指定“開始”和“結束”值:
班級 符號
\d “數字”[0-9]
\w “文字符號”[A-Za-z0-9_]
\s “空間”[ \t\r\n\f]
「word」字元類別\w特別有用,因為各種程式語言中的有效識別碼(變數名稱、函數名稱等)通常需要此字元集。我們可以用它\w來簡化我們之前看到的正規表示式:
模式:\\[az]字串
:` \n`、` \r`、` \t`和 ` \f`空白字符,` \. `、` \\ ` 和 ` \[ `不是。
匹配:   ^^ ^^ ^^ ^^	
使用\w我們可以這樣寫:
模式:\\\w
字串:` \n`、` \r`、` \t`和 ` \f`是空白字符,` \. `、` \\ ` 和 ` \[ `不是。
匹配:   ^^ ^^ ^^ ^^	

2個幸運任務:

如你我所知,在 Java 中,識別符(變數、類別、函數等的名稱)只能以字母a- zA- Z、美元符號$或底線開頭_。(底線當然是不好的風格,但編譯器會跳過它,譯者註)。其餘字元必須是“word”字元\w。使用一個或多個字元類,建立正規表示式以在以下三字元序列中搜尋有效的 Java 識別碼:
圖案:
字串:   __e $12 .x2 foo Bar 3mm
符合:^^^ ^^^ ^^^ ^^^	
(解決方案) 美國社會安全號碼 (SSN) 是 9 位數字,格式為 XXX-XX-XXXX,其中每個 X 可以是任意數字[0-9]。使用一個或多個字元類,編寫正規表示式以在下面的清單中找到格式正確的 SSN:
圖案:
字串:113-25=1902 182-82-0192 H23-_3-9982 1I1-O0-E38B
配對:              ^^^^^^^^^^^
解決方案RegEx:20個簡短步驟掌握正規表示式。第 2 部分: 掌握正規表示式的 20 個簡短步驟。第 3 部分 :正規表示式:掌握正規表示式的 20 個簡短步驟。第 4 部分。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION