简体   繁体   中英

Why does Matcher.find() return false when run after Matcher.lookingAt()?

I've noticed that calling Matcher.lookingAt() affects Matcher.find() . I ran lookingAt() in my code and it returned true . When I then ran find() so that I can start returning matches, i got false . If I remove the lookingAt() call, find() returns true and prints my matches. Does anyone know why?

Trial1:

Matcher matches = Pattern.compile("T\\d+").matcher("T234bird");
System.out.println(matches.lookingAt()); //after running this, find() will return false
while (matches.find())
    System.out.println(matches.group());
//Output: true

Trial2:

Matcher matches = Pattern.compile("T\\d+").matcher("T234bird");
//System.out.println(matches.lookingAt()); //without this, find() will return true
while (matches.find())
    System.out.println(matches.group());
//Output: T234

Trial3:

Matcher matches = Pattern.compile("T\\d+").matcher("T234bird");
while (matches.lookingAt()) 
    System.out.println(matches.group());
//Output: T234 T234 T234 T234 ... till crash
//I understand why this happens. It's not my question but I just included it in case someone may try to suggest it

Ultimately, what I want to achieve is: First confirm that the match is at the beginning of the string, then print it. I ended up doing:

Matcher matches = Pattern.compile("T\\d+").matcher("T234bird");
if(matches.lookingAt()) 
    System.out.println(matches.group());
//Output: T234

This solves my problem but my question is: Does anyone know why lookingAt() affect find() ?

The call to .lookingAt() matches and consumes T234 , so the following .find() call starts off at bird - a non-match.

You need to reset your matcher object in order to start at the beginning again.

Or simply use a start-of-string anchor in your regex and use .find() right away:

Matcher matches = Pattern.compile("^T\\d+").matcher("T234bird");
if (matches.find())
    System.out.println(matches.group());

In trial 1, the call lookingAt matches T234 , and your subsequent call to find starts looking for a match at the end of the previous match . If you want to go back to the beginning of the string you need to call Matcher.reset() . This is explained in the documentation for Matcher.find() :

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.

Note that lookingAt works with start , end , and group the same way find does, so you can just do this if you are only interested in the beginning of the string:

Matcher matches = Pattern.compile("T\\d+").matcher("T234bird");
if (matches.lookingAt())
    System.out.println(matches.group());

You have to use if instead of while here, because lookingAt always starts looking at the beginning of the string, not at the end of the previous match, so while just loops forever.

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