Java Regex中的matches()和find()之间的区别

我试图理解matches()find()之间的区别。

根据Javadoc(根据我的理解), matches()将search整个string,即使它find了它正在查找的内容, find()将在它find正在查找的内容时停止。

如果这个假设是正确的,我不会看到每当你想要使用matches()而不是find() ,除非你想要计算它find的匹配数。

在我看来,String类应该具有find()而不是matches()作为内置方法。

所以总结一下:

  1. 我的假设是否正确?
  2. 什么时候使用matches()而不是find()有用?

matches尝试将expression式与整个string匹配,并在模式的开始处和$末尾隐式添加^ ,这意味着它不会查找子string。 因此这个代码的输出:

 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 */ 

123a123b的子string,所以find()方法输出true。 matches()只看到a123b这是不一样的123 ,从而输出错误。

如果整个string匹配给定的模式,则matches返回true。 find试图find匹配模式的子string。

如果完整string匹配, matches()将只返回true。 find()会尝试find匹配正则expression式的子string中的下一个匹配项。 注意强调“下一个”。 这意味着,多次调用find()的结果可能不一样。 另外,通过使用find()你可以调用start()来返回子string匹配的位置。

 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()); 

会输出:

发现:错误
发现:真实 - 位置4
发现:真实的位置17
find:真实的位置20
发现:错误
发现:错误
匹配:错误
 -----------
find:真实 - 位置0
发现:错误
发现:错误
匹配:是的
匹配:是的
匹配:是的
匹配:是的

所以,如果Matcher对象没有被重置,那么多次调用find()时要小心,即使正则expression式被^$包围以匹配完整的string。

matches(); 不缓冲,但find()缓冲区。 find()searchstring的末尾,索引结果,并返回布尔值和相应的索引。

这就是为什么当你有这样的代码

 1:Pattern.compile("[az]"); 2:Pattern.matcher("0a1b1c3d4"); 3:int count = 0; 4:while(matcher.find()){ 5:count++: } 

4:使用模式结构的正则expression式引擎会读取整个代码(按照regex[single character]指定的索引来查找至less一个匹配项)。如果find这样的匹配项,则将索引为循环将根据索引结果执行,否则如果没有进行提前计算,比如matches() ;不会。因为匹配的string的第一个字符不是字母表,所以while语句永远不会执行。

find()会考虑正则expression式的子string,因为matches()会考虑完整的expression式。

只有当expression式的子string匹配模式时, 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 } }