matches
试图将表达式与整个字符串匹配,并隐式地在模式的开头添加^
,在末尾添加$
,这意味着它不会查找子字符串。 因此,此代码的输出为:
public static void main(String[] args) throws ParseException {
Pattern p = Pattern.compile("\\d\\d\\d");
Matcher m = p.matcher("a123b");
System.out.println(m.find());
System.out.println(m.matches());
p = Pattern.compile("^\\d\\d\\d$");
m = p.matcher("123");
System.out.println(m.find());
System.out.println(m.matches());
}
/* output:
true
false
true
true
*/
123
是a123b
的子字符串,所以find()
方法输出true。matches()
只会“看到”a123b
,这与123
不同,因此输出false。matchers()
不仅仅是一个带有隐含前置符^和后置符$的 find()
。请注意,如果未在 reset()
前调用 .find()
多次,则可能会得到不同的结果,而 matches()
总是返回相同的结果。请参见下面的我的回答。 - L. Holandamatches
函数会在整个字符串与给定的模式完全匹配时返回true。而find
函数则是尝试找到一个与模式匹配的子字符串。
matches(p)
与find("^" + p + "$")
是相同的。 - jensgram"123abc123".matches("[a-z]+")
会失败,就像 "123abc123".find("^[a-z]+$")
一样。我的观点是,matches()
要求完全匹配,就像同时使用起始和结束锚点的 find()
一样。 - jensgramPattern.compile("some pattern").matcher(str).matches()
等同于 Pattern.compile("^some pattern$").matcher(str).find()
。 - AlexR...("some pattern").matcher(str).matches()
并不完全等同于...("^some pattern$").matcher(str).find()
,只有在第一个调用中才是这样。请参见下面的答案。 - L. Holandamatches()
- 仅当整个字符串匹配时才会返回truefind()
- 尝试在与正则表达式匹配的子字符串中查找下一个匹配项。请注意,在find()
的情况下强调了"下一个"。这意味着,多次调用find()
的结果可能不同。此外,通过使用find()
,您可以调用start()
来返回子字符串匹配的位置。
final Matcher subMatcher = Pattern.compile("\\d+").matcher("skrf35kesruytfkwu4ty7sdfs");
System.out.println("Found: " + subMatcher.matches());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find() + " - position " + subMatcher.start());
System.out.println("Found: " + subMatcher.find());
System.out.println("Found: " + subMatcher.find());
System.out.println("Matched: " + subMatcher.matches());
System.out.println("-----------");
final Matcher fullMatcher = Pattern.compile("^\\w+$").matcher("skrf35kesruytfkwu4ty7sdfs");
System.out.println("Found: " + fullMatcher.find() + " - position " + fullMatcher.start());
System.out.println("Found: " + fullMatcher.find());
System.out.println("Found: " + fullMatcher.find());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());
System.out.println("Matched: " + fullMatcher.matches());
Found: false
Found: true - position 4
Found: true - position 17
Found: true - position 20
Found: false
Found: false
Matched: false
-----------
Found: true - position 0
Found: false
Found: false
Matched: true
Matched: true
Matched: true
Matched: true
所以,如果Matcher
对象没有被重置,请谨慎多次调用find()
,即使正则表达式使用^
和$
匹配整个字符串。
find()
会将子字符串与正则表达式进行匹配,而matches()
则会将整个表达式作为一个整体进行匹配。
find()
仅在子字符串与模式匹配时返回true。
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d");
String candidate = "Java123";
Matcher m = p.matcher(candidate);
if (m != null){
System.out.println(m.find());//true
System.out.println(m.matches());//false
}
}
matches();
没有缓存,但是 find()
会缓存。 find()
首先搜索整个字符串,索引结果,并返回布尔值和相应的索引。
这就是为什么当你有像下面的代码时:
1:Pattern.compile("[a-z]");
2:Pattern.matcher("0a1b1c3d4");
3:int count = 0;
4:while(matcher.find()){
5:count++: }
在第四步,使用模式结构的正则表达式引擎将按照regex[single character]
指定的索引逐个读取您的代码,以查找至少一个匹配项。如果找到了这样的匹配项,它将被索引,然后循环将基于索引结果执行;否则,如果它没有像matches()
一样进行前向计算,则while语句将永远不会执行,因为匹配字符串的第一个字符不是字母。
Matcher
对象,多次调用find()
方法可能会返回不同的结果。请参考下面的答案。 - L. Holandajava.util.regex.Pattern.compile(regex).matcher(input).matches()
和java.util.regex.Pattern.compile(regex).matcher(input).find()
。 - Jens Piegsa