sunleo
sunleo

Reputation: 10943

Java Regex Pattern Matcher.matches() before Matcher.find() Strange behaviour

I tried this example just interchanging two lines it gives different outputs why

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

///changes happens here

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

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

output :

[email protected]

true

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

output : true

Upvotes: 3

Views: 5457

Answers (3)

CodeDreamer
CodeDreamer

Reputation: 444

The javadoc for the method replaceAll(String replacement) states the following "Invoking this method changes this matcher's state. If the matcher is to be used in further matching operations then it should first be reset."

So, I think you are finding this discrepancy because the matcher is not longer in the same state after replaceall. Try resetting the matcher after replaceall.

Upvotes: 2

Chris
Chris

Reputation: 2481

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

Find starts wherever it was left off from the previous use of the matcher

First instance, this means the start of the inputString.

However, as matches() takes the whole inputString into account, this moves the pointer to the end. As a result, it finds no more and find() in this case is false (as its subsequent)

Upvotes: 2

Alex
Alex

Reputation: 25613

Extracted from Matcher.find documentation

find

public boolean find()

Attempts to find the next subsequence of the input sequence that matches the pattern. This method starts at the beginning of this matcher's region, or, if a previous invocation of the method was successful and the matcher has not since been reset, at the first character not matched by the previous match.

If the match succeeds then more information can be obtained via the start, end, and group methods.

Returns: true if, and only if, a subsequence of the input sequence matches this matcher's pattern

So, since you called Matcher.matches which attempts to match the whole String, and you did not reset the matcher, it tried to find starting after the first match. As there is only one match, it does not find anything.

Upvotes: 5

Related Questions