简体   繁体   中英

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(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 pattern
  • pattern.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, 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM