Java Matcher.find 方法
上次修改时间:2025 年 4 月 20 日
Matcher.find 方法是 Java 正则表达式 API 的关键部分。它扫描输入序列,寻找与模式匹配的下一个子序列。与 matches 不同,它不需要整个输入都匹配。
如果找到匹配项,该方法返回 true,否则返回 false。每次调用 find 都会从前一个匹配结束的地方开始。这使得它非常适合在单个输入字符串中查找多个匹配项。
基本定义
Matcher:一个解释模式并在输入字符串上执行匹配操作的类。通过 matcher 方法从 Pattern 对象创建。
Pattern:正则表达式的编译表示。用于创建 Matcher 对象,这些对象将字符序列与正则表达式进行匹配。
find:尝试查找与模式匹配的输入的下一个子序列。如果找到则返回 true,并更新内部状态以进行进一步操作。
find 的基本用法
此示例演示了使用 find 在字符串中定位模式的最简单方法。我们将在一个示例文本中搜索单词 "Java"。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BasicFindExample {
public static void main(String[] args) {
String text = "Java is powerful. Java is versatile. Learn Java!";
Pattern pattern = Pattern.compile("Java");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println("Found 'Java' at index " + matcher.start());
}
}
}
代码编译一个与字面量 "Java" 匹配的模式。find 方法扫描文本以查找匹配项。每个成功的匹配都会打印找到的子字符串的起始索引。循环将继续,直到找不到更多匹配项。
查找多个模式
此示例显示了 find 如何按顺序定位多个不同的模式。我们将在我们的文本中搜索 "Java" 和 "powerful"。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MultiplePatternsExample {
public static void main(String[] args) {
String text = "Java is powerful. Java is versatile. Learn Java!";
Pattern pattern1 = Pattern.compile("Java");
Pattern pattern2 = Pattern.compile("powerful");
Matcher matcher1 = pattern1.matcher(text);
Matcher matcher2 = pattern2.matcher(text);
System.out.println("Finding 'Java':");
while (matcher1.find()) {
System.out.println("Found at " + matcher1.start());
}
System.out.println("\nFinding 'powerful':");
if (matcher2.find()) {
System.out.println("Found at " + matcher2.start());
}
}
}
我们为不同的模式创建了两个单独的 Matcher 实例。第一个找到 "Java" 的所有出现,而第二个查找 "powerful"。请注意,find 可以在循环和单个检查中使用。
使用 find 与分组
此示例演示了 find 如何与捕获组一起使用。我们将从文本中提取 "dd-mm-yyyy" 格式的日期。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FindWithGroupsExample {
public static void main(String[] args) {
String text = "Dates: 12-05-2023, 15-06-2023, invalid 32-13-2023";
Pattern pattern = Pattern.compile("(\\d{2})-(\\d{2})-(\\d{4})");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
System.out.println("Day: " + matcher.group(1));
System.out.println("Month: " + matcher.group(2));
System.out.println("Year: " + matcher.group(3) + "\n");
}
}
}
正则表达式模式定义了三个用于日、月和年的捕获组。每个 find 调用都会定位一个日期匹配项。然后,group 方法提取完全匹配或特定组件。无效的日期将被跳过。
find() 与起始和结束位置
此示例展示了如何使用带有开始和结束参数的 find,将搜索限制到输入字符串的特定区域。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FindWithRegionExample {
public static void main(String[] args) {
String text = "First Java, then Python, then more Java";
Pattern pattern = Pattern.compile("Java");
Matcher matcher = pattern.matcher(text);
// Search only in the first half of the string
matcher.region(0, text.length() / 2);
System.out.println("Searching in region [0-" + (text.length()/2) + "]:");
while (matcher.find()) {
System.out.println("Found at " + matcher.start());
}
// Reset region to search entire string
matcher.reset();
System.out.println("\nSearching entire string:");
while (matcher.find()) {
System.out.println("Found at " + matcher.start());
}
}
}
region 方法限制了 find 的搜索范围。第一个循环仅在字符串的前半部分查找匹配项。在 reset 之后,第二个搜索涵盖整个输入。
find() vs lookingAt() vs matches()
此示例将 find 与类似的方法 lookingAt 和 matches 进行比较,以演示它们之间的差异。
package com.zetcode;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FindComparisonExample {
public static void main(String[] args) {
String text = "Java is great";
Pattern pattern = Pattern.compile("Java");
Matcher matcher = pattern.matcher(text);
System.out.println("matches(): " + matcher.matches());
System.out.println("lookingAt(): " + matcher.lookingAt());
System.out.println("find(): " + matcher.find());
// Reset matcher for second find() test
matcher.reset();
System.out.println("\nAfter reset:");
System.out.println("find() at start: " + matcher.find());
}
}
matches 检查整个字符串是否与该模式匹配。lookingAt 仅检查开头。find 在字符串中的任何位置搜索模式。在 reset 之后,find 再次从头开始搜索。
带有单词边界的 find
此示例演示了将单词边界 (\b) 与 find 结合使用,以仅匹配整个单词。
package com.zetcode;
import java.util.regex.*;
public class FindWithBoundariesExample {
public static void main(String[] args) {
String text = "Java JavaScript JavaFX";
Pattern pattern = Pattern.compile("\\bJava\\b");
Matcher matcher = pattern.matcher(text);
System.out.println("Finding whole word 'Java':");
while (matcher.find()) {
System.out.println("Found at " + matcher.start());
}
// Compare without word boundaries
System.out.println("\nFinding 'Java' without boundaries:");
matcher = Pattern.compile("Java").matcher(text);
while (matcher.find()) {
System.out.println("Found at " + matcher.start());
}
}
}
第一个搜索使用单词边界仅查找独立的 "Java" 单词。第二个搜索查找所有出现,包括那些在其他单词(如 "JavaScript")中的单词。单词边界确保我们仅匹配完整的单词。
find() 与大小写不敏感
此示例展示了如何使用带有不区分大小写匹配的 find 来定位单词,无论它们的大小写如何。
package com.zetcode;
import java.util.regex.*;
public class CaseInsensitiveFindExample {
public static void main(String[] args) {
String text = "Java JAVA java jAvA";
Pattern pattern = Pattern.compile("java", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(text);
System.out.println("Case-insensitive search for 'java':");
while (matcher.find()) {
System.out.println("Found '" + matcher.group() +
"' at " + matcher.start());
}
}
}
CASE_INSENSITIVE 标志使模式匹配无论大小写如何。每个 find 调用都会在不同的情况下定位 "java" 的另一个变体。实际匹配的文本通过 group 返回。
来源
本教程涵盖了 Matcher.find 方法的基本方面。掌握此方法是 Java 中有效模式匹配的关键。
作者
列出所有Java教程。