Java Regex中的matches()和find()之间的区别
我试图理解matches()
和find()
之间的区别。
根据Javadoc(根据我的理解), matches()
将search整个string,即使它find了它正在查找的内容, find()
将在它find正在查找的内容时停止。
如果这个假设是正确的,我不会看到每当你想要使用matches()
而不是find()
,除非你想要计算它find的匹配数。
在我看来,String类应该具有find()
而不是matches()
作为内置方法。
所以总结一下:
- 我的假设是否正确?
- 什么时候使用
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 */
123
是a123b
的子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 } }