我试过这个例子只是交换两行,它给出了不同的输出
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);
}
输出: 真
答案 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之后重置匹配器。