本教程适用于JDK 8。本页中描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
有关Java SE 9及后续版本中更新的语言特性的摘要,请参阅Java语言更改。
有关所有JDK版本的新功能、增强功能以及已删除或弃用选项的信息,请参阅JDK发布说明。
本节介绍了Matcher类的一些其他有用的方法。为方便起见,下面列出的方法根据功能进行分组。
索引方法提供了有用的索引值,精确地显示匹配在输入字符串中的位置:
public int start():返回上一个匹配的起始索引。public int start(int group):返回上一个匹配操作期间给定组捕获的子序列的起始索引。public int end():返回最后一个字符匹配之后的偏移量。public int end(int group):返回上一个匹配操作期间给定组捕获的子序列最后一个字符之后的偏移量。查找方法会检查输入字符串并返回一个布尔值,指示模式是否被找到。
public boolean lookingAt():尝试从区域的开头开始,将输入序列与模式进行匹配。public boolean find():尝试查找与模式匹配的输入序列的下一个子序列。public boolean find(int start):重置此匹配器,然后尝试从指定的索引开始,查找与模式匹配的输入序列的下一个子序列。public boolean matches():尝试将整个区域与模式进行匹配。替换方法是用于替换输入字符串中的文本的有用方法。
public Matcher appendReplacement(StringBuffer sb, String replacement): 实现非终端的追加和替换步骤。 public StringBuffer appendTail(StringBuffer sb): 实现终端的追加和替换步骤。public String replaceAll(String replacement): 将输入序列中与模式匹配的每个子序列替换为给定的替换字符串。public String replaceFirst(String replacement): 将输入序列中与模式匹配的第一个子序列替换为给定的替换字符串。public static String quoteReplacement(String s): 返回指定字符串的字面替换字符串。此方法生成的字符串将作为 Matcher 类的 appendReplacement 方法中的字面替换 s。生成的字符串将与将 s 视为字面序列的字符序列相匹配。斜杠('\')和美元符号('$')将不具有特殊含义。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);
int count = 0;
while(m.find()) {
count++;
System.out.println("匹配次数 "
+ count);
System.out.println("start(): "
+ m.start());
System.out.println("end(): "
+ m.end());
}
}
}
输出: 匹配编号 1 起始位置(): 0 结束位置(): 3 匹配编号 2 起始位置(): 4 结束位置(): 7 匹配编号 3 起始位置(): 8 结束位置(): 11
你可以看到这个例子使用了单词边界来确保字母"d" "o" "g"不仅仅是较长单词中的子字符串。它还提供了关于匹配出现在输入字符串中的位置的一些有用信息。start方法返回在前一个匹配操作期间捕获的给定组的子序列的起始索引,end返回匹配的最后一个字符的索引加一。
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) {
// 初始化
pattern = Pattern.compile(REGEX);
matcher = pattern.matcher(INPUT);
System.out.println("当前的REGEX是: "
+ REGEX);
System.out.println("当前的INPUT是: "
+ INPUT);
System.out.println("lookingAt(): "
+ matcher.lookingAt());
System.out.println("matches(): "
+ matcher.matches());
}
}
当前的REGEX是: foo 当前的INPUT是: fooooooooooooooooo lookingAt(): true matches(): false
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);
INPUT = m.replaceAll(REPLACE);
System.out.println(INPUT);
}
}
输出:猫说喵喵。所有的猫都会说喵喵。
在第一个版本中,所有的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);
// get a matcher object
Matcher m = p.matcher(INPUT);
INPUT = m.replaceAll(REPLACE);
System.out.println(INPUT);
}
}
输出:-foo-foo-foo-
如果只替换模式的第一次出现,只需调用replaceFirst而不是replaceAll,它接受相同的参数。
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-
java.lang.String中的匹配器方法等效为了方便起见,String类也模拟了一些Matcher方法:
public String replaceFirst(String regex, String replacement): 用给定的替换字符串替换此字符串中与给定正则表达式匹配的第一个子字符串。以str.replaceFirst(regex, repl)形式调用此方法将产生与Pattern.compile(regex).matcher(str).replaceFirst(repl)表达式完全相同的结果。public String replaceAll(String regex, String replacement): 用给定的替换字符串替换此字符串中与给定正则表达式匹配的每个子字符串。以str.replaceAll(regex, repl)形式调用此方法将产生与Pattern.compile(regex).matcher(str).replaceAll(repl)表达式完全相同的结果。