Matcher.find()之前的Java Regex Pattern Matcher.matches()奇怪的行为

时间:2012-11-13 14:08:15

标签: java regex

我试过这个例子只是交换两行,它给出了不同的输出

String inputString = "username@gmail.com"; 
String pattern="([a-z]+@)([a-z]+)(\\.[a-z]+)";
Pattern p = Pattern.compile(pattern); 
Matcher m = p.matcher(inputString); 

///这里发生了变化

if(m.find()) 
{
   String resultString = m.replaceAll("$1xxxx$3"); 
   System.out.println(resultString); 
}

System.out.println(m.matches());//line to be changed

输出:

username@xxxx.com

System.out.println(m.matches());//line changed     
if(m.find()) 
{
   String resultString = m.replaceAll("$1xxxx$3"); 
   System.out.println(resultString); 
}

输出: 真

3 个答案:

答案 0 :(得分:5)

摘自Matcher.find文档

  

查找

     

public boolean find()

     

试图找到下一个子序列   与模式匹配的输入序列。这个方法从   这个匹配器区域的开头,,或者,如果之前的调用   该方法是成功的,匹配器从那以后就没有被重置了   第一个字符与上一场比赛不匹配

     

如果匹配成功,则可以通过获得更多信息   开始,结束和分组方法。

     

返回:当且仅当输入序列的子序列时才返回true   匹配此匹配器的模式

所以,既然你调用Matcher.matches试图匹配整个String,并且你没有重置匹配器,它就试图在第一次匹配后找到。因为只有一个匹配,所以没有找到任何东西。

答案 1 :(得分:2)

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/regex/Matcher.html#find()

从以前使用匹配器的任何地方开始查找

首先,这意味着inputString的开始。

但是,由于matches()将整个inputString考虑在内,因此将指针移动到结尾。结果,它找不到更多,并且在这种情况下find()是假的(作为其后续的)

答案 2 :(得分:2)

方法replaceAll(String replacement)的javadoc声明如下 “调用此方法会更改此匹配器的状态。如果要在进一步匹配操作中使用匹配器,则应首先重置它。”

所以,我认为你发现这种差异是因为在替换后匹配器不再处于相同的状态。尝试在replaceall之后重置匹配器。