2

I have to perform partial pattern matching, so I tested pattern matching against the following input

Pattern p = Pattern.compile("hello");
Matcher m = p.matcher("[a-z]");

Can anybody explains me why

System.out.println(m.find() || m.hitEnd());

prints true while

System.out.println(m.hitEnd());

prints false?

2
  • @BrianRoach: you're right, it's not really about pattern matching. The question is basically how the hitEnd() method works, which can be confusing. See my answer for details. Commented Jan 21, 2013 at 15:09
  • @stefano I hope it is intended by you, that the pattern is hello, and the input string is [a-z]. Because [a-z] looks like a regular expression, and hello like a input string. Commented Jan 21, 2013 at 15:13

3 Answers 3

2

Look at this program:

Pattern p = Pattern.compile("hello");
Matcher m = p.matcher("[a-z]");
System.out.println(m.hitEnd()); // prints false
System.out.println(m.find());  // prints false
System.out.println(m.hitEnd()); // prints true

Notice, the first call of m.hitEnd() returns false. Look at JavaDoc, it says:

Returns true if the end of input was hit by the search engine in the last match operation performed by this matcher.

Here it returns false, because it is called before the call of m.find(), so the matcher hasn't performed any match operations, yet. After the call of m.find() it returns true (because find() consumes the complete input string and hits the end). The meaning of that is also explained in JavaDoc:

When this method returns true, then it is possible that more input would have changed the result of the last search.

When this returns true, it means the matcher hit the end of the input. In this case, hit means reached, not matched. (The input was completely consumed by the matcher).

EDIT

I hope it is wanted by you, that [a-z] is the input string for your regular expression hello, and it's not the other way around. If you had

Pattern p = Pattern.compile("[a-z]"); // The regex needs to be compiled.
Matcher m = p.matcher("hello");       // The input is given to the matcher
while (m.find()) {                    // In this case, returns true 5 times
    System.out.println(m.group() + ", ");
}

your output would be

h, e, l, l, o, 
Sign up to request clarification or add additional context in comments.

5 Comments

No it doesn't print what you (and I) expected. In the order it prints false, false, true. The find() method doesn't seem to work as expected, this is my probem.
@stefano: right, was a typo of mine ;) I never expected find() to be true. I definitely think you have the pattern and the input string mixed up. See my edit.
Ok, understood. Honestly, the doc is a little bit ambigous (at least for a non-eglish person). I swapped the parameters of Patter.compile(...) and Matcher.find(...).
So wait a second... does this mean my current solution is incorrect in context to this question? And the original was right? WE WILL GET THIS RIGHT EVENTUALLY, lol
@stefano: It actually makes sense. This way, you can compile a pattern once, and feed it many input strings.
2

UPDATE:

Because m.find() itself processes the pattern fully, but does not find a match (and returns false). The pattern is fully consumed after this call, so hitEnd() will result true.

In the second call, the pattern is not consumed, so hitEnd() returns false.

For hitEnd() the Javadoc says:

Returns true if the end of input was hit by the search engine in the last match operation performed by this matcher.

Reflecting on comment from @jlordo : Maybe you want to change the pattern and the text:

Pattern p = Pattern.compile("[a-z]");
Matcher m = p.matcher("hello");

because "[a-z]" rather looks like a pattern.

4 Comments

m.find() returns false, because the pattern hello cannot be found in the string [a-z].
Yes, I removed my downvote. You are answering the question correct. But it doesn't solve OP's problem, he confused the regex with the input string.
@jlordo That's true, that was the misleading part... Interesting, but if we would change the pattern and the text (as probably the OP originally wished), we would get the same result... :)
Yes, if you read the comments below my answer, the OP says that he confused regex and input. I think the rest of the question is then obsolete.
0
System.out.println(m.find() || m.hitEnd());

m.find() returns a boolean - that boolean is false. We just processed hit the end of input searching through - that makes m.hitend() result in true. false || true equates to true, accordingly.

The previous operation hit the end - hitend() returns true if..well, here's javadoc:

Returns true if the end of input was hit by the search engine in the last 
match operation performed by this matcher.

We DIDN'T reach the end...on the last operation. So hitend() is false. Successive calls would result in false.

6 Comments

m.find() returns false, because the pattern hello cannot be found in the string [a-z].
@PinkElephantsOnParade: Why don't you upvote helpful questions and answers?
@jlordo I do, typically; I think my profile shows a pretty active vote record. I'll probably wait until this question is fully resolved to distribute my votes.
@PinkElephantsOnParade: Ok ;) I am more of a quick voter type :D
@PinkElephantsOnParade m.find() will always return false, as long as the pattern is hello! In our case (Pattern.compile("hello");) the pattern is hello. What you write only is good for Pattern.compile("[a-z]");
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.