pattern.matcher() vs pattern.matches()
I am wondering why the results of the java regex pattern.matcher() and pattern.matches() differ when provided the same regular expression and same string
String str = "hello+";
Pattern pattern = Pattern.compile("\\+");
Matcher matcher = pattern.matcher(开发者_JAVA百科str);
while (matcher.find()) {
System.out.println("I found the text " + matcher.group() + " starting at "
+ "index " + matcher.start() + " and ending at index " + matcher.end());
}
System.out.println(java.util.regex.Pattern.matches("\\+", str));
The result of the above are:
I found the text + starting at index 5 and ending at index 6
false
I found that using an expression to match the full string works fine in case of matches(".*\\+")
.
pattern.matcher(String s)
returns a Matcher
that can find patterns in the String s
. pattern.matches(String str)
tests, if the entire String (str
) matches the pattern.
In brief (just to remember the difference):
pattern.matcher
- test if the string contains-a patternpattern.matches
- test if the string is-a pattern
Matcher.find()
attempts to find the next subsequence of the input sequence that matches the pattern.
Pattern.matches(String regex, CharSequence input)
compiles the regex into a Matcher
and returns Matcher.matches()
.
Matcher.matches
attempts to match the entire region (string) against the pattern (Regex).
So, in your case, the Pattern.matches("\\+", str)
returns a false since str.equals("+")
is false.
From the Javadoc, see the if, and only if, the entire region section
/**
* Attempts to match the entire region against the pattern.
*
* <p> If the match succeeds then more information can be obtained via the
* <tt>start</tt>, <tt>end</tt>, and <tt>group</tt> methods. </p>
*
* @return <tt>true</tt> if, and only if, <b>the entire region</b> sequence
* matches this matcher's pattern
*/
public boolean matches() {
return match(from, ENDANCHOR);
}
So if your String was just "+", you'd get a true result.
matches tries to match the expression against the entire string. Meaning, it checks whether the entire string is a patern or not. conceptually think it like this, it implicitly adds a ^ at the start and $ at the end of your pattern.
For, String str = "hello+", if you want matches() to return true, you need to have pattern like ".\+."
I hope this answered your question.
Pattern.matches is testing the whole String, in your case you should use:
System.out.println(java.util.regex.Pattern.matches(".*\\+", str));
Meaning any string and a + symbol
I think your question should really be "When should I use the Pattern.matches()
method?", and the answer is "Never." Were you expecting it to return an array of the matched substrings, like .NET's Matches
methods do? That's a perfectly reasonable expectation, but no, Java has nothing like that.
If you just want to do a quick-and-dirty match, adorn the regex with .*
at either end, and use the string's own matches()
method:
System.out.println(str.matches(".*\\+.*"));
If you want to extract multiple matches, or access information about a match afterward, create a Matcher instance and use its methods, like you did in your question. Pattern.matches()
is nothing but a wasted opportunity.
Matcher matcher = pattern.matcher(text);
In this case, a matcher object instance will be returned which performs match operations on the input text by interpreting the pattern. Then we can use,matcher.find()
to match no. of patterns from the input text.
(java.util.regex.Pattern.matches("\\+", str))
Here, the matcher object will be created implicitly and a boolean will be returned which matches the whole text with the pattern. This will work as same as the str.matches(regex)
function in String.
The code equivalent to java.util.regex.Pattern.matches("\\+", str)
would be:
Pattern.compile("\\+").matcher(str).matches();
method find
will find the first occurrence of the pattern in the string.
精彩评论