0

Why does adding an if statement before the while loop result in the first match being removed?

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class testRegex {
    public static void main(String[]args) {
        Pattern p = Pattern.compile("[a-zA-Z0-9]+");
        Matcher m = p.matcher("Name, 245 Street, City, Country, 101010");
        
        System.out.println(m.find());
        
        if(m.find()) {
            while(m.find()) {
                System.out.println(m.group());
            }
        } else {
            System.out.println("Nothing found");
        }
     }
}

The output without the if is correct.

Name
245
Street
City
Country
101010

Adding the if or anything before the while loop for that matter results in this:

245
Street
City
Country
101010

What am I doing wrong and how can I correct this? I'm doing this on Eclipse IDE.

4
  • how can I correct this? - remove the if Commented Aug 23, 2022 at 6:41
  • 7
    Based on documentation, find() "attempts to find the next subsequence of the input sequence that matches the pattern", so when you have println or if before while, they "consume" one or several find() iterations. Commented Aug 23, 2022 at 6:43
  • 1
    Ok. I need the if find to print something like "Nothing found" if nothing matched. Commented Aug 23, 2022 at 6:45
  • Very strange reason to close this question. How is this not reproducible or was caused by typos? Commented Aug 24, 2022 at 6:17

5 Answers 5

4

Here is an alternative approach using Java 8 streams:

final Pattern p = Pattern.compile("[a-zA-Z0-9]+");
Matcher m = p.matcher("Name, 245 Street, City, Country, 101010");
    
List<String> res = m.results().map(MatchResult::group)
                  .collect(Collectors.toList());
if (res.isEmpty()) {
    System.out.println("Nothing found");
} else {
    System.out.println(res);
}

Output:

[Name, 245, Street, City, Country, 101010]
Sign up to request clarification or add additional context in comments.

Comments

2

m.find() changes state, goes to the next match if present.

    //NO: System.out.println(m.find());
   
    if (m.find()) {
        System.out.println("Found:");
        do {
            System.out.println(m.group());
        } while (m.find());
    } else {
        System.out.println("Nothing found");
    }

2 Comments

Of course, if you want to print something, you can assign the result of m.find() to a variable, print it and check it in the if condition.
Added alternative println for when something was found. When not found there already is a println.
2

Why not use matcher.reset()?

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class testRegex {
    public static void main(String[]args) {
        Pattern p = Pattern.compile("[a-zA-Z0-9]+");
        Matcher m = p.matcher("Name, 245 Street, City, Country, 101010");
        
        System.out.println(m.find());
        m.reset();

        if(m.find()) {
            m.reset();
            while(m.find()) {
                System.out.println(m.group());
            }
        } else {
            System.out.println("Nothing found");
        }
     }
}

Comments

1

Each call of "m.find" will move to the next match in within the search String. So you have to remember the Finding of the first call of m.find() or you use the while loop without the if statement. With a boolean flag you could keep track whether you found something or not to decide whether you want to print "Nothing found" afterwards.

Something like:

      boolean foundSomething = false;
           
      while(m.find()) {
        foundSomething = true;
        System.out.println(m.group());
      }
      if(!foundSomething){        
        System.out.println("Nothing found");
      }

Comments

0

Don't use while alone because it is a fulfillment of the condition if it doesn't find what you are looking for it moves to the next use for or do-while

1 Comment

Ok. How would you do it with a for loop? I'm been trying for sometime.

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.