Java 提供了 java.util.regex 包來與正則表達式進行模式匹配。Java 正則表達式和 Perl 編程語言非常相似,也容易學習。
正則表達式是一個特殊的字符序列,有助于你用一種專門的語法模式來匹配或找到其他字符串或字符串集。他們可以用來搜索編輯或是操縱文本和數(shù)據(jù)。
java.util.regex 包主要包含了下面的三個類:
Pattern 類:一個 Pattern 對象是正則表達式編譯表示。 Pattern 類沒有提供公共的構造函數(shù)。要創(chuàng)建一個 Pattern 對象,你必須首先調(diào)用他的公用靜態(tài)編譯方法來獲得 Pattern 對象。這些方法的第一個參數(shù)是正則表達式。
Matcher 類:一個 Matcher 對象是用來解釋模式和執(zhí)行與輸入字符串相匹配的操作。和 Pattern 類一樣 Matcher 類也是沒有構造方法的,你需要通過調(diào)用 Pattern 對象的 matcher 方法來獲得 Matcher 對象。
捕獲組是一種將多個字符抽象為一個處理單元的方法。他們通過用括號將字符分組來創(chuàng)建。舉個例子,正則表達式(dog)創(chuàng)建一個組包含字符 "d","o"和"g"。
捕獲組通過從左向右計算括號的個數(shù)來進行計數(shù)。在正則表達式((A)(B(C)))中,這里有四個組:
((A)(B(C)))
(A)
(B(C))
為了在表達式中計算有多少個組,可以調(diào)用 matcher 對象中的 groupCount 方法。 groupCount 方法返回一個 int 類型來顯示正則表達式中的捕獲組的數(shù)量。
這里也有特殊的組,組0總是代表了整個表達式。這個組不包含在 groupCount 負責的所有組內(nèi)。
下面的例子展現(xiàn)了如何從給定的字符數(shù)字串中找出數(shù)字串
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
public static void main( String args[] ){
// String to be scanned to find the pattern.
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(\\d+)(.*)";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find( )) {
System.out.println("Found value: " + m.group(0) );
System.out.println("Found value: " + m.group(1) );
System.out.println("Found value: " + m.group(2) );
} else {
System.out.println("NO MATCH");
}
}
}
這將會得到下面的結果
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0
這里的表格記錄了 java 中可用的所有正則表達式的元字符語法:
子表達式 | 匹配對應 |
---|---|
^ | 匹配一行的開頭 |
$ | 匹配一行的結尾 |
. | 匹配除了換行符的任何單個字符,也可以利用 m 選項允許它匹配換行符 |
[...] | 匹配括號內(nèi)的任意單個字符。 |
[^...] | 匹配不在括號內(nèi)的任意單個字符。 |
\A | 整個字符串的開始 |
\z | 整個字符串的結束 |
\Z | 整個字符串的結束,除了最后一行的結束符 |
re* | 匹配0或者更多的前表達事件 |
re+ | 匹配1個或更多的之前的事件 |
re? | 匹配0或者1件前表達事件 |
re{ n} | 匹配特定的n個前表達事件 |
re{ n,} | 匹配n或者更多的前表達事件 |
re{ n, m} | 匹配至少n最多m件前表達事件 |
a| b | 匹配a或者b |
(re) | 正則表達式組匹配文本記憶 |
(?: re) | 沒有匹配文本記憶的正則表達式組 |
(?> re) | 匹配無回溯的獨立的模式 |
\w | 匹配單詞字符 |
\W | 匹配非單詞字符 |
\s | 匹配空格。等價于 [\t\n\r\f] |
\S | 匹配非空格 |
\d | 匹配數(shù)字. 等價于 [0-9] |
\D | 匹配非數(shù)字 |
\A | 匹配字符串的開始 |
\Z | 匹配字符串的末尾,如果存在新的一行,則匹配新的一行之前 |
\z | 匹配字符串的末尾 |
\G | 匹配上一次匹配結束的地方 |
\n | 返回參考捕獲組號“N” |
\b | 不在括號里時匹配單詞邊界。在括號里時匹配退格鍵 |
\B | 匹配非詞邊界 |
\n, \t, etc. | 匹配換行符,回車符,制表符,等 |
\Q | 引用字符的初始,結束于\E |
\E | 結束由\Q開始的引用 |
這里列出了有用的實例方法
index方法提供有用的指標值,精確地顯示輸入字符串中相匹配的位置:
SN | 方法描述 |
---|---|
1 | public int start() 返回之前匹配開始索引 |
2 | public int start(int group) 返回被之前匹配操作得出的組捕獲的子序列 |
3 | public int end() 返回在最后一個字符匹配之后的偏移量 |
4 | public int end(int group) 返回在之前匹配操作得出的組捕獲的子序列之后的偏移量 |
Study 方法根據(jù)輸入字符串返回一個布爾類型數(shù)據(jù)來指示該模式是否被找到。
SN | 方法描述 |
---|---|
1 | public boolean lookingAt() 試圖匹配輸入序列,從模式的起始位置開始 |
2 | public boolean find() 試圖找到下一個輸入序列的子序列來進行模式匹配 |
3 | public boolean find(int start) 重置匹配,并且試圖找到下一個從某個特定位置開始的輸入序列的子序列來進行模式匹配 |
4 | public boolean matches() 試圖去匹配模式的整個區(qū)域 |
Replacement 方法是在一個輸入字符串中替換文本的有效方法。
SN | 方法描述 |
---|---|
1 | public Matcher appendReplacement(StringBuffer sb, String replacement) 實現(xiàn)一個無目的的添加和代替步驟 |
2 | public StringBuffer appendTail(StringBuffer sb) 實現(xiàn)一個有目的的添加和代替步驟 |
3 | public String replaceAll(String replacement) 代替每一個輸入序列的子序列,與給出的代替字符串的模式匹配 |
4 | public String replaceFirst(String replacement) 代替第一個輸入序列的子序列,與給出的代替字符串的模式匹配 |
5 | public static String quoteReplacement(String s) 返回一個特定字符串逐字替換的字符串。這個方法產(chǎn)生了一個字符串將作為文本替換的 Matcher 類的 appendreplacement 方法 |
下面是一個例子,計算 "cats" 在輸入字符串中出現(xiàn)的次數(shù):
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
private static final String REGEX = "\\bcat\\b";
private static final String INPUT =
"cat cat cat cattie cat";
public static void main( String args[] ){
Pattern p = Pattern.compile(REGEX);
Matcher m = p.matcher(INPUT); // get a matcher object
int count = 0;
while(m.find()) {
count++;
System.out.println("Match number "+count);
System.out.println("start(): "+m.start());
System.out.println("end(): "+m.end());
}
}
}
這是產(chǎn)生的結果:
Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
Match number 4
start(): 19
end(): 22
你可以看到這個例子用次邊界來確保字母 "c""a""t" 不僅僅是一個長單詞子串。它也給出了一些關于在輸入字符串中匹配位置的有用的信息。
start方法返回值是之前end方法返回值加1。
matches 和 lookingAt 方法都是按照一定的模式匹配輸入序列,兩種方法不同的是 matches 方法需要匹配整個輸入序列,找出其中不同的。
兩種方法都總是開始于輸入字符串的起始位置。這里是一個例子:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
private static final String REGEX = "foo";
private static final String INPUT = "fooooooooooooooooo";
private static Pattern pattern;
private static Matcher matcher;
public static void main( String args[] ){
pattern = Pattern.compile(REGEX);
matcher = pattern.matcher(INPUT);
System.out.println("Current REGEX is: "+REGEX);
System.out.println("Current INPUT is: "+INPUT);
System.out.println("lookingAt(): "+matcher.lookingAt());
System.out.println("matches(): "+matcher.matches());
}
}
這是產(chǎn)生的結果:
Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false
replaceFirst 和 replaceAll 方法替換了匹配給定正則表達式的文本。正如它們的名字所表明的,replaceFirst 替換第一個情況,而 replaceAll 替換所有的情況。
這里是解釋功能的例子:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
private static String REGEX = "dog";
private static String INPUT = "The dog says meow. " +
"All dogs say meow.";
private static String REPLACE = "cat";
public static void main(String[] args) {
Pattern p = Pattern.compile(REGEX);
// get a matcher object
Matcher m = p.matcher(INPUT);
INPUT = m.replaceAll(REPLACE);
System.out.println(INPUT);
}
}
以上將會產(chǎn)生如下結果:
The cat says meow. All cats say meow.
Matcher 類還提供了 appendReplacement 和 appendTail 兩種方法來替換文本。
這里是解釋功能的例子:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
private static String REGEX = "a*b";
private static String INPUT = "aabfooaabfooabfoob";
private static String REPLACE = "-";
public static void main(String[] args) {
Pattern p = Pattern.compile(REGEX);
// get a matcher object
Matcher m = p.matcher(INPUT);
StringBuffer sb = new StringBuffer();
while(m.find()){
m.appendReplacement(sb,REPLACE);
}
m.appendTail(sb);
System.out.println(sb.toString());
}
}
以上將會產(chǎn)生如下結果:
-foo-foo-foo-
PatternSyntaxException 是一個未檢查的、在正則表達式模式指示語法錯誤的特例。PatternSyntaxException 類提供了以下的方法來幫助你找出問題所在:
SN | 方法描述 |
---|---|
1 | public String getDescription() 檢索錯誤的描述 |
2 | public int getIndex() 檢索誤差指標 |
3 | public String getPattern() 檢索錯誤的正則表達式模式 |
4 | public String getMessage() 返回一個包含語法錯誤的描述及其指標的多行字符串、錯誤的正則表達式模式以及顯示模式里誤差指標 |