我們提請您注意 Java 語言正規表示式簡短指南的翻譯,該指南由 Jeff Friesen 為 JavaWorld網站編寫。為了方便閱讀,我們將文章分成幾個部分。
在 Java 程式中使用正規表示式 API 來識別和描述模式
Java 的字元和各種字串資料類型為模式匹配提供低級支持,但將它們用於此目的通常會顯著增加程式碼複雜性。透過使用 Regex API(「正規表示式 API」)可以獲得更簡單、效能更高的程式碼。本教學將幫助您開始使用正規表示式和 Regex API。我們將首先一般性地討論包中三個最有趣的類java.util.regex
,然後查看該類的內部Pattern
並探索其複雜的模式匹配構造。 注意力: 您可以從此處下載本文示範應用程式的原始程式碼(由 Jeff Friesen 為 JavaWorld 網站建立)。
什麼是正規表示式?
正規表示式(regular expression/regex/regexp)是一個字串,它是描述某組字串的模式。此模式決定哪些行屬於該集合。此模式由文字和元字元組成,即具有特殊含義而不是字面含義的字元。模式搜尋是透過文字搜尋來尋找匹配項,即與正規表示式模式相符的字串。Java 透過其 Regex API 支援模式來匹配。此 API 由三個類別組成:Pattern
、Matcher
和PatternSyntaxException
,位於套件中java.util.regex
:
- 類別對象
Pattern
,也稱為模板,是編譯後的正規表示式。 - 類別物件
Matcher
(或稱匹配器)是用於在字元序列(其類別實作介面java.lang.CharSequence
並用作文字來源的物件)中尋找匹配項的模式解釋機制。 - 類別物件
PatternSyntaxException
用於描述無效的正規表示式模式。
java.lang.String
. 例如,僅當呼叫字串與正規表示式完全匹配時,該函數boolean matches (String regex)
才會傳回。 true
regex
便捷的方法 |
---|
matches() 類別的其他面向正規表示式的便捷方法String 以與 Regex API 類似的方式在底層實作。 |
正規表示式演示
我創建了一個應用程式來演示 Java 正規表示式以及,和RegexDemo
的各種方法。以下是該演示應用程式的原始程式碼。清單 1. 正規表示式演示 Pattern
Matcher
PatternSyntaxException
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
public class RegexDemo
{
public static void main(String[] args)
{
if (args.length != 2)
{
System.err.println("usage: java RegexDemo regex input");
return;
}
// Преобразуем символьные последовательности начала новой строки (\n) в символы начала строки.
args[1] = args[1].replaceAll("\\\\n", "\n");
try
{
System.out.println("regex = " + args[0]);
System.out.println("input = " + args[1]);
Pattern p = Pattern.compile(args[0]);
Matcher m = p.matcher(args[1]);
while (m.find())
System.out.println("Found [" + m.group() + "] starting at "
+ m.start() + " and ending at " + (m.end() - 1));
}
catch (PatternSyntaxException pse)
{
System.err.println("Неправильное регулярное выражение: " + pse.getMessage());
System.err.println("Описание: " + pse.getDescription());
System.err.println("Позиция: " + pse.getIndex());
System.err.println("Неправильный шаблон: " + pse.getPattern());
}
}
}
main
類別 方法所做的第一件事RegexDemo
是檢查其命令列。它需要兩個參數:第一個是正規表示式,第二個是將在其中搜尋正規表示式的輸入文字。您可能需要在輸入文字中使用換行符號(\n)
。這只能透過指定字元\
後接字元來完成n
。此函數main()
將此字元序列轉換為 Unicode 值 10。 大部分程式碼RegexDemo
包含在try-catch
. 該區塊try
首先輸出給定的正則表達式和輸入文本,然後創建一個Pattern
存儲編譯後的正則表達式的物件(編譯正則表達式是為了提高模式匹配性能)。從物件中提取匹配器Pattern
並用於迭代搜尋匹配項,直到找到所有匹配項。該區塊catch
呼叫幾個類別方法PatternSyntaxException
來檢索有關異常的有用資訊。此資訊被順序輸出到輸出流。目前還沒有必要了解程式碼如何運作的細節:當我們在本文的第二部分研究 API 時,它們就會變得清晰。但是,您必須編譯清單 1。取得清單 1 中的程式碼,然後在命令提示字元中鍵入下列命令進行編譯RegexDemo
: javac RegexDemo.java
Pattern 類及其構造
這個類別Pattern
是構成 Regex API 的三個類別中的第一個,是正規表示式的編譯表示。類 SDK 文件Pattern
描述了各種正規表示式構造,但如果您不積極使用正規表示式,則本文檔的某些部分可能會令人困惑。什麼是量詞?貪婪量詞、不情願量詞和占有量詞有什麼差別?什麼是字元類別、邊界匹配器、反向引用和嵌入式標誌表達式?我將在以下部分中回答這些問題和其他問題。
文字字串
最簡單的正規表示式構造是文字字串。為了使模式匹配成功,輸入文字的某些部分必須與該構造的模式相符。考慮以下範例:java RegexDemo apple applet
在此範例中,我們嘗試apple
在輸入文字中尋找模式的匹配項applet
。以下結果顯示找到的匹配:
regex = apple
input = applet
Found [apple] starting at 0 and ending at 4
我們在輸出中看到正規表示式和輸入文本,然後apple
在小程式中看到成功檢測的指示。另外,本場比賽的起始位置和結束位置分別為:0
和4
。開始位置表示文字中找到匹配項的第一個位置,結束位置表示匹配項的最後一點。現在假設我們給了以下命令列: java RegexDemo apple crabapple
這次我們得到以下結果,有不同的開始和結束位置:
regex = apple
input = crabapple
Found [apple] starting at 4 and ending at 8
否則,使用 andapplet
作為正則表達式apple
- 輸入文本,將找不到匹配項。整個正規表示式必須匹配,但在這種情況下,輸入文字不包含t
after apple
。
元字元
更有趣的正規表示式結構將文字字元與元字元結合。例如,在正規表示式 中a.b
,點元字元(.)
表示a
和 b 之間的任何字元。請考慮以下範例: java RegexDemo .ox "The quick brown fox jumps over the lazy ox."
此範例既用作.ox
正規表示式又The quick brown fox jumps over the lazy ox.
用作輸入文字。RegexDemo
在文字中搜尋以任意字元開頭並以 結尾的匹配項ox.
其執行結果如下:
regex = .ox
input = The quick brown fox jumps over the lazy ox.
Found [fox] starting at 16 and ending at 18
Found [ ox] starting at 39 and ending at 41
在輸出中,我們看到兩個匹配項:fox
和ox
(前面有一個空格字元)。元字符在第一種情況下.
匹配一個字符,在第二種情況下匹配一個空格。f
如果.ox
用元字元替換它會發生什麼.
?也就是說,我們得到以下命令行的結果: java RegexDemo . "The quick brown fox jumps over the lazy ox."
由於點元字符匹配任何字符,因此RegexDemo
將輸出輸入文本的所有字符(包括尾隨點字符)找到的匹配項:
regex = .
input = The quick brown fox jumps over the lazy ox.
Found [T] starting at 0 and ending at 0
Found [h] starting at 1 and ending at 1
Found [e] starting at 2 and ending at 2
Found [ ] starting at 3 and ending at 3
Found [q] starting at 4 and ending at 4
Found [u] starting at 5 and ending at 5
Found [i] starting at 6 and ending at 6
Found [c] starting at 7 and ending at 7
Found [k] starting at 8 and ending at 8
Found [ ] starting at 9 and ending at 9
Found [b] starting at 10 and ending at 10
Found [r] starting at 11 and ending at 11
Found [o] starting at 12 and ending at 12
Found [w] starting at 13 and ending at 13
Found [n] starting at 14 and ending at 14
Found [ ] starting at 15 and ending at 15
Found [f] starting at 16 and ending at 16
Found [o] starting at 17 and ending at 17
Found [x] starting at 18 and ending at 18
Found [ ] starting at 19 and ending at 19
Found [j] starting at 20 and ending at 20
Found [u] starting at 21 and ending at 21
Found [m] starting at 22 and ending at 22
Found [p] starting at 23 and ending at 23
Found [s] starting at 24 and ending at 24
Found [ ] starting at 25 and ending at 25
Found [o] starting at 26 and ending at 26
Found [v] starting at 27 and ending at 27
Found [e] starting at 28 and ending at 28
Found [r] starting at 29 and ending at 29
Found [ ] starting at 30 and ending at 30
Found [t] starting at 31 and ending at 31
Found [h] starting at 32 and ending at 32
Found [e] starting at 33 and ending at 33
Found [ ] starting at 34 and ending at 34
Found [l] starting at 35 and ending at 35
Found [a] starting at 36 and ending at 36
Found [z] starting at 37 and ending at 37
Found [y] starting at 38 and ending at 38
Found [ ] starting at 39 and ending at 39
Found [o] starting at 40 and ending at 40
Found [x] starting at 41 and ending at 41
Found [.] starting at 42 and ending at 42
引用元字符 |
---|
若要將元字符或任何其他元字符指定. 為正則表達式構造中的文字字符,必須透過以下方式之一對其進行轉義:
String regex = "\\."; 反斜線(例如,\\. 或\\Q.\\E )。不要重複命令列參數中的反斜線。 |
字元類
有時您必須將要尋找的匹配項限制為特定字元集。例如,在文本中搜尋元音a
、e
、i
和,每次出現元音字母o
都u
被視為匹配。在解決此類問題時,字元類別將幫助我們定義方括號 ( [ ]
) 元字元之間的字元集。此類別Pattern
支援簡單字元類別、範圍類別、逆、並、交集和減法類別。我們現在來看看所有這些。
簡單字元類
簡單的字元類別由並排放置的字元組成,並且僅匹配這些字元。例如,該類別[abc]
匹配字元a
,b
和c
。考慮以下範例: java RegexDemo [csw] cave
如您從結果中看到的,在此範例中只有c
與 中 相符的字元cave
:
regex = [csw]
input = cave
Found [c] starting at 0 and ending at 0
倒排字元類
倒排字元類別以元字元開頭^
,並且僅匹配那些不包含在其中的字元。例如,該類別匹配除,和[^abc]
之外的所有字元。請考慮以下範例: 請注意,在我的作業系統 (Windows) 上,需要雙引號,因為 shell 將它們視為轉義字元。如您所看到的,在本範例中,僅找到了字元、和,它們在 中存在匹配: a
b
c
java RegexDemo "[^csw]" cave
^
a
v
e
cave
regex = [^csw]
input = cave
Found [a] starting at 1 and ending at 1
Found [v] starting at 2 and ending at 2
Found [e] starting at 3 and ending at 3
範圍字元類
範圍字元類別由用連字號 (-
) 分隔的兩個字元組成。從連字符左邊的字符開始到右邊的字符結束的所有字符都是該範圍的一部分。例如,範圍[a-z]
匹配所有小寫拉丁字母。這相當於定義一個簡單的類別[abcdefghijklmnopqrstuvwxyz]
。考慮以下範例: 此範例將僅匹配在 中匹配的java RegexDemo [a-c] clown
字元: c
clown
regex = [a-c]
input = clown
Found [c] starting at 0 and ending at 0
Java 中的正規表示式,第 2 部分 Java 中的正規表示式,第 3 部分 Java 中的正規表示式,第 4 部分 Java 中的正規表示式,第 5 部分
GO TO FULL VERSION