JavaRush /Java Blog /Random-TW /Java 中正規表示式的基礎知識。第三部分
articles
等級 15

Java 中正規表示式的基礎知識。第三部分

在 Random-TW 群組發布
讓我們繼續研究正規表示式。在本文中,我們將研究預先定義的字元類別以及量化(搜尋序列)。 Java 中正規表示式的基礎知識。 第 3 - 1 部分

預定義字元類

類 APIPattern包含預先定義的字元類,為常用的正規表示式提供方便的捷徑。 Java 中正規表示式的基礎知識。 第 3 - 2 部分在此表中,左列中的構造是右列中表達式的簡寫表示。例如,\d表示數字(0-9),\w表示任何大寫或小寫字母、底線或數字)。盡可能使用預先定義的字元類別。這將使您的程式碼更易於閱讀和修復錯誤。以反斜線開頭的結構稱為轉義或受保護。在之前的文章中,我們已經討論過使用反斜線或符號轉義特殊字元\Q並將\E其用作常規字元。如果將反斜線與常規字元(文字)一起使用,則需要轉義反斜線才能編譯表達式。
private final String REGEX = "\\d"; // цифра
在這個例子中\d,一個正規表示式;程式編譯需要額外的反斜線。我們的測試程式直接從控制台讀取正規表示式,因此不需要額外的斜線。下面的範例示範了預定義字元類別的使用: Java 中正規表示式的基礎知識。 第 3 - 3 部分Java 中正規表示式的基礎知識。 第 3 - 4 部分在前三個範例中,正規表示式只是「.」(點特殊字元),表示任何字元。因此,在所有情況下搜尋都是成功的。其他範例使用預先定義的字元類,我們在上表中討論了其含義。

量詞

Java 中正規表示式的基礎知識。 第 3 - 4 部分量詞可讓您指定字元在字串中出現的次數。讓我們仔細看看貪婪、惰性和非常貪婪量詞如何運作的複雜性。乍一看,量詞 X?, X?? 和 X?+ 的工作方式相同:“X 出現一次或根本不存在。” 這些量詞的實作略有不同,我們將在下面討論。

零長度匹配

讓我們從貪婪的開始。讓我們寫三個不同的正規表示式:帶有特殊字元 ?、* 或 + 的字母「a」。讓我們看看如果在空白行上測試這些正規表示式會發生什麼: Java 中正規表示式的基礎知識。 第 3 - 5 部分在上面的範例中,前兩種情況搜尋成功,因為表達式 a? a* 允許字串中缺少字元 a。另請注意,開始匹配索引和最後匹配索引相同 (0)。由於輸入字串沒有長度,因此程式在第一個位置找不到任何內容:)。這種情況稱為零長度匹配。此類匹配發生在多種情況下:當輸入行為空時、在輸入行的開頭、在該行的最後一個字元之後或在該行的字元之間。零長度匹配很容易發現:它們在同一位置開始和結束。讓我們看一些零長度匹配的更多範例。讓我們透過更多範例來探討零長度匹配。讓我們將輸入字串更改為字元“a”並觀察一個有趣的效果: Java 中正規表示式的基礎知識。 第 3 - 6 部分所有三個量詞都找到了字元“a”,但前兩個量詞(允許不存在字元)在位置1 處找到了零長度匹配- 在字串的最後一個字元之後。發生這種情況是因為程式將字元“a”視為字串並“運行”它,直到不再有匹配項為止。根據所使用的量詞,程式將或不會在字串末尾找到“nothing”。現在讓我們將輸入字串更改為五個字母「a」的序列: Java 中正規表示式的基礎知識。 第 3 - 7 部分正規表示式 a?分別找出字串中每個字母的符合項目。表達式 a* 找到兩個匹配項:字元序列「a」'和位置 5 處的零長度匹配項。最後,正規表示式 a+ 只找到字元「a」的序列,而沒有找到「nothing」:) 如果給出包含不同字元的字串作為輸入,會發生什麼事?例如,「ababaaaab」: Java 中正規表示式的基礎知識。 第 3 - 8 部分字元「b」位於位置 1、3 和 8,且程式在這些位置找到零長度匹配。正規表示式a? 不關注“b”,而只是查找字元“a”是否存在(或不存在)。如果量詞允許不存在“a”,則字串中除“a”之外的所有字元都會顯示為零長度匹配。若要尋找給定長度的序列,只需在大括號中指定長度即可: Java 中正規表示式的基礎知識。 第 3 - 9 部分正規表示式 a{3} 搜尋包含三個「a」字元的序列。第一行中沒有找到任何內容,因為該行中沒有足夠的 a。第二個包含程式找到的 3 個字元。第三個測試還在字串的開頭找到匹配項。第三個字元之後的所有內容都不滿足正規表示式,在下面的程式碼中它滿足正則表達式,並且將有多個匹配項: Java 中正規表示式的基礎知識。 第 3 - 10 部分要指定最小序列長度,請使用:
Enter your regex: a{3,}
Enter input string to search: aaaaaaaaa
I found the text "aaaaaaaaa" starting at index 0 and ending at index 9.
在此範例中,程式只找到一個符合項,因為該字串滿足 (3) 個「a」字元的最小序列長度要求。最後,設定最大序列長度: Java 中正規表示式的基礎知識。 第 3 - 11 部分在本例中,第一個匹配在第六個字元處結束。第二個匹配包含第六個之後的字符,因為 它們滿足最小長度要求。如果字串短一個字符,則不會有第二個匹配項。

將字元組和類別與量詞一起使用

到目前為止,我們已經在包含相同字元的字串上測試了量詞。量詞僅適用於單個字符,因此正則表達式“abc+”將匹配包含“ab”和“c”的字串一次或多次。它不會表示“abc”一次或多次。但量詞可以與組和字符類結合使用,例如 [abc]+(a 或 b 或 c,一次或多次)或 (abc)+(“abc”一次或多次)。讓我們尋找一組字元(狗),一行中出現三次: Java 中正規表示式的基礎知識。 第 3 - 12 部分在第一個範例中,程式找到了一個匹配項,因為 量詞擴展到一組字元。如果刪除括號,量詞 {3} 將僅適用於字母「g」。您也可以將量詞與字元類別一起使用: Основы регулярных выражений в Java. Часть 3 - 13{3} 量詞適用於第一個範例中括號中的字元類,而在第二個範例中,僅適用於字元「c」。

貪婪量詞、惰性量詞和過度貪婪量詞之間的區別

貪婪、不情願和所有格量詞之間存在細微差別。貪婪量詞之所以如此命名,是因為它們試圖找到最長的可能匹配:程式首先嘗試「吃掉」整個字串,如果未找到匹配,則丟棄一個字元並重複搜索,直到找到匹配或沒有更多的字符了。另一方面,懶惰的人從行的開頭開始,一個接一個地添加字符,直到找到匹配項。最後,嫉妒量化會掃描整個字串一次,而不是像貪婪那樣刪除字元。為了進行演示,我們將使用字串 xfooxxxxxxfoo。 Основы регулярных выражений в Java. Часть 3 - 14第一個範例使用貪婪的 .* 量詞來尋找任何字元(0 次或多次),後面跟著字元「f」「o」「o」。由於cantifier是貪婪的,所以找到的匹配包含整個字串。貪婪量詞不會找到字串中的所有匹配項,因為 第一步,掃描整個字串後,它將找到匹配項並完成工作。第二個範例是惰性的,從行的開頭開始,逐個字元地添加。該程式首先檢查“空”,但由於 序列“foo”不在行的開頭,搜尋將繼續添加字元“x”,之後將在索引 0 和 4 之間找到第一個匹配項。搜尋將繼續,直到行尾第二個匹配將在索引4 和13 之間找到。第三個例子沒有找到重合,因為量詞是嫉妒的。在本例中,正規表示式 .*+ 「吃掉」了整行,沒有為「foo」留下任何內容。當您需要丟棄字串中不需要的任何內容時,請使用嫉妒量詞,它將比等效的貪婪量詞更有效。就這樣!原始碼連結:Java 中正規表示式的基礎知識。第三部分
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION