Jenna Kwon
Jenna Kwon

Reputation: 1252

Java regex - one liner for counting matches

Is there a one liner to replace the while loop?

String formatSpecifier = "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])";
Pattern pattern = Pattern.compile(formatSpecifier);
Matcher matcher = pattern.matcher("hello %s my name is %s");

// CAN BELOW BE REPLACED WITH A ONE LINER?
int counter = 0;
while (matcher.find()) {
    counter++;
}

Upvotes: 5

Views: 4305

Answers (2)

Adrian Shum
Adrian Shum

Reputation: 40036

Personally I don't see any reason to aim for one-liner given the original code is already easy to understand. Anyway, several ways if you insists:

1. Make a helper method

make something like this

static int countMatches(Matcher matcher) {
  int counter = 0;
  while (matcher.find())
    counter++;
  return counter;
}

so your code become

int counter = countMatches(matcher);

2. Java 9

Matcher in Java 9 provides results() which returns a Stream<MatchResult>. So your code becomes

int counter = matcher.results().count();

3. String Replace

Similar to what the other answer suggest.

Here I am replacing with null character (which is almost not used in any normal string), and do the counting by split:

Your code become:

int counter = matcher.replaceAll("\0").split("\0", -1).length - 1;

Upvotes: 4

Alexandre Fenyo
Alexandre Fenyo

Reputation: 4809

Yes: replace any occurrence by a char that can be neither in the pattern nor in the string to match, then count the number of occurrences of this char. Here I choose X, for the example to be simple. You should use a char not so often used (see UTF-8 special chars for instance).

final int counter = pattern.matcher("hello %s my name is %s").replaceAll("X").replaceAll("[^X]", "").length();

Value computed for counter is 2 with your example.

Upvotes: 0

Related Questions