13.10 Matcher类的方法
这一小节介绍Matcher类的其他一些有用的方法。为了方便起见,按照功能对下面列出的方法分组。
13.10.1 索引方法
索引方法(index method)提供有用的索引值,精确地指出在输入字符串中的什么位置找到了匹配:
l public int start()——返回前一个匹配的开始索引。
l public int start(int group)——返回前一个匹配操作期间,给定组捕获的子序列的开始索引。
l public int end()——返回最后一个匹配的字符之后的偏移量。
l public int end(int group)——返回前一个匹配操作期间,给定组捕获的子序列的最后一个字符之后的偏移量。
13.10.2 研究方法
研究方法(study method)检查输入字符串,并且返回一个布尔值,指出是否找到了模式。
l public boolean lookingAt()——从一个区域的开头开始试图把输入序列和模式进行匹配。
l public boolean find()——试图查找输入序列中和模式匹配的下一个子序列。
l public boolean find(int start)——重新设置这个匹配器,然后从指定的索引开始,试图查找输入序列中和模式匹配的下一个子序列。
l public boolean matches()——试图把整个区域和模式进行匹配。
13.10.3 替换方法
替换方法(replacement method)是用于替换输入字符串中文本的有用的方法:
l public Matcher appendReplacement(StringBuffer sb, String replacement)——实现非终结符的附加和替换步骤。
l public StringBuffer appendTail(StringBuffer sb)——实现终结符的附加和替换步骤。
l public String replaceAll(String replacement)——使用给定的替换字符串,替换输入序列中和模式匹配的每个子序列。
l public String replaceFirst(String replacement)——使用给定的替换字符串,替换输入序列中和模式匹配的第一个子序列。
l public static String quoteReplacement(String s)——返回指定String的字面量替换String。这个方法生成的String像Matcher类的appendReplacement方法中的字面量替换s那样工作。生成的String和当作字面量序列的s中的字符序列匹配。不会赋予反斜线(\)和美元符号($)特殊含义。
13.10.4 使用start和end方法
下面是一个例子MatcherDemo.java,它计算输入字符串中单词“dog”的出现次数:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class MatcherDemo {
private static final String REGEX = "\\bdog\\b";
private static final String INPUT =
"dog dog dog doggie dogg";
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());
}
}
}
输出为
Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
可以发现,这个例子使用单词边界确保字母“d”“o”“g”不仅仅是更长的单词中的子字符串。它还给出关于匹配出现在输入字符串中什么位置的一些有用信息。start方法返回前一个匹配操作过程中,给定组捕获的子序列的开始索引,而end方法返回匹配的最后一个字符的索引加1。
13.10.5 使用matches和lookingAt方法
matches和lookingAt方法都试图把输入序列和模式进行匹配。但是,二者的区别在于matches要求整个输入字符串匹配,而lookingAt不是这样。两个方法总是从输入字符串的开头开始。下面是完整代码MatchesLooking.java:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class MatchesLooking {
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) {
// Initialize
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());
}
}
程序输出如下:
Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false
13.10.6 使用replaceFirst(String)和replaceAll(String)
replaceFirst和replaceAll方法提供和给定正则表达式匹配的文本。就像它们的名字所指出的,replaceFirst替换第一次出现,而replaceAll替换所有出现。下面是代码ReplaceDemo.java:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class ReplaceDemo {
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);
Matcher m = p.matcher(INPUT); // get a matcher object
INPUT = m.replaceAll(REPLACE);
System.out.println(INPUT);
}
}
输出如下:
The cat says meow. All cats say meow.
在第一个版本中,dog的所有出现都被替换为cat。但是为什么不再进一步呢?除了替换简单的字面量(例如dog)之外,还可以替换匹配任何正则表达式的文本。这个方法的API声称“给定正则表达式a*b、输入aabfooaabfooabfoob和替换字符串-,对这个表达式的匹配器调用这个方法将生成字符串-foo-foo-foo-”。
下面是ReplaceDemo2.java的代码:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class ReplaceDemo2 {
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);
Matcher m = p.matcher(INPUT); // get a matcher object
INPUT = m.replaceAll(REPLACE);
System.out.println(INPUT);
}
}
输出如下:
-foo-foo-foo-
为了只替换模式的第一次出现,只需把调用replaceAll换成调用replaceFirst即可。它接受相同参数。
13.10.7
appendReplacement(StringBuffer,String)和
appendTail(StringBuffer)方法
Matcher类还提供appendReplacement和appendTail方法用于文本替换。下面的例子RegexDemo.java使用这两个方法达到和replaceAll相同的目的:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexDemo {
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);
Matcher m = p.matcher(INPUT); // get a matcher object
StringBuffer sb = new StringBuffer();
while(m.find()){
m.appendReplacement(sb,REPLACE);
}
m.appendTail(sb);
System.out.println(sb.toString());
}
}
输出如下:
-foo-foo-foo-
13.10.8 java.lang.String中和Matcher等同的方法
为了便利起见,String类也模拟了几个Matcher方法:
l public String replaceFirst(String regex, String replacement)——使用给定的替换,替换这个字符串中和给定正则表达式匹配的第一个子字符串。调用这个方法的str.replaceFirst(regex, repl)形式产生的结果和表达式Pattern.compile (regex).matcher (str).replaceFirst(repl)相同。
l public String replaceAll(String regex, String replacement)——使用给定的替换,替换这个字符串中和给定正则表达式匹配的每个子字符串。调用这个方法的str.replaceAll(regex,repl)形式产生的结果和表达式Pattern.compile (regex).matcher(str). replaceAll(repl)相同。






