Java Basics Part 16/20 - Regular Expressions
目錄
Java 爲正則表達式的模式匹配提供了 java.util.regex 包。
正則表達式主要用來匹配或者查詢符合某個模式的字符串。
java.util.regex 包主要包含以下三個類:
- Pattern Class: 正則表達式編譯後 產生 Pattern 對象。 Pattern 類沒有構造器,爲了產生一個 Pattern,必須調用 Pattern 的 compile() 方法,它會返回一個 Pattern 對象。Pattern 類的靜態方法的第一個參數都是一個 正則表達式。
- Matcher Class: Matcher 對象是一個引擎,用來解釋 pattern,並且在輸入字符串上執行匹配操作。與 Pattern 類一樣,Matcher 類也不提供構造器。可以 Pattern 對象的 matcher() 方法來獲得一個 Matcher 對象。
- PatternSyntaxException: 用來指示 正則表達式 有語法錯誤的異常類。
捕獲組
捕獲組把多個字符當成一個整體。把多個字符放在一個括號中,就創建了一個捕獲組。例如,正則表達式 (dog) 就創建了一個組,這個組裏含有字母 d,o 和 g。
可以從左到右對左半邊括號計數來得到捕獲組的數目。例如,表達式 ((A)(B(C))),有以下幾個組:
- ((A)(B(C)))
- (A)
- (B(C))
- (C)
爲了得到表達式中的捕獲組數目,可以調用 matcher 對象的 groupCount() 方法。這個方法返回了一個 matcher 的 pattern 中含有的捕獲組的數目。
還有一個特殊的組,group 0,這個組總是代表整個表達式。groupCount 不會對這個組進行計數。
舉例:
下面這個例子演示了怎樣在字符串中找到一個數字。
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");
}
}
}
// output
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0
可見,group 0 就是整個表達式。
正則表達式語法
下標列出了 Java 中所有可用的的正則表達式元字符。
Subexpression | Matches |
---|---|
^ | 一行的開頭 |
$ | 一行的結尾 |
. | 任意字符除了換行符 |
[…] | 匹配中括號中的任一個字符 |
[^…] | 匹配任意一個不在中括號中的字符 |
\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\b\r\f] |
\S | 匹配非空白字符 |
\d | 匹配數字 |
\D | 匹配非數字 |
\G | 最後一次匹配結束的匹配點 |
\n | 反向引用第 n 個捕獲組 |
\b | 在中括號外是 匹配單詞邊界,中括號內是匹配 backspace |
\B | 匹配非單詞邊界 |
\n, \t, etc | 匹配 換行,tab 等 |
\Q | 所有的字符都是普通字符,包括轉義字符,直到遇到\E |
\E | 與 \Q 對應 |
Matcher 類方法
Index 方法
Index 方法可以精確返回 匹配 出現在 輸入中 的位置
SN | Methods with Description |
---|---|
1 | public int start():返回前一個匹配的開始位置 |
2 | public int start(int group):返回匹配的組的開始的位置 |
3 | public int end():返回匹配的最後一個字符之後的偏移 |
4 | public int end(int group):返回匹配的組的最後一個字符之後的偏移 |
Study 方法
Study 方法查看輸入字符串,並且返回一個 boolean,說明 pattern 是否能匹配。
SN | Methods with Description |
---|---|
1 | public boolean lookingAt():嘗試使用 pattern 從起始位置匹配輸入序列 |
2 | public boolean find():嘗試使用 pattern 匹配輸入序列 |
3 | public boolean find(int start):嘗試從 start 處使用 pattern 匹配輸入序列 |
4 | public boolean matches():嘗試使用 pattern 匹配整個輸入序列 |
Replacement 方法
Replacement 方法主要用來替換字符串中的文本
SN | Methods with Description |
---|---|
1 | public Matcher appendReplacement(StringBuffer sb, String replacement):把匹配的內容換成 replacement |
2 | public StringBuffer appendTail(StringBuffer sb):剩下的沒有匹配的全都添加到 sb 中 |
3 | public String replaceAll(String replacement) |
4 | public String replaceFirst(String replacement) |
5 | public static String quoteReplacement(String s) |
栗子
start() 和 end()
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());
}
}
}
// output
atch number 1
start(): 0
end(): 3
atch number 2
start(): 4
end(): 7
atch number 3
start(): 8
end(): 11
atch number 4
start(): 19
end(): 22
matches() 和 lookingAt()
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());
}
}
// output
Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false
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);
}
}
// output
The cat says meow. All cats say meow.
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());
}
}
// output
-foo-foo-foo-
PatternSyntaxException 類的方法
PatternSyntaxException 用來表明正則表達式中的語法錯誤的。
SN | Methods with Description |
---|---|
1 | public String getDescription():返回錯誤描述 |
2 | public int getIndex():返回錯誤號 |
3 | public String getPattern():返回錯誤的正則表達式 |
4 | public String getMessage():一堆錯誤信息,基本上是以上三者的彙總吧 |