tags:

views:

34

answers:

3

I want to check if string doesn't have more than 5 numbers. I can do it this way:

Matcher matcher = Pattern.compile("\\d").matcher(val);
i = 0;
while (matcher.find()) {
    i++;
}

However I would like to do it without while (because we are using regex validation framework). I want to be able to match strings like

A2sad..3f,3,sdasad2..2

+2  A: 

Try this regular expression:

^\D*(?:\d\D*){0,5}$

\d is a single digit and \D is the complement to that, so any character except a digit. (?:…) is like a normal grouping except its submatch cannot be referenced.

This regular expression allows any non-digit characters at the start, followed by at most five sequences of a single digit followed by optional non-digit characters.

Gumbo
@Bart K.: What makes you think that? It’s semantically equivalent to yours.
Gumbo
@Bart K.: it'd match 0-4 digits as well. There's a \D* at the beginning.
reko_t
@Gumbo, you edited your answer. When I replied, you had `{5}`.
Bart Kiers
thanks, i choose to accept Bart K. because its the easiest to understand.
01
+3  A: 

This regex matches strings containing a max of 5 digits:

^(\D*\d){0,5}\D*$

And if you want to match strings consisting of exactly 5 digits, do:

^(\D*\d){5}\D*$

Note that inside a java.lang.String literal, you'll need to escape the backslashes:

boolean match = "A2sad..3f,3,sdasad2..2".matches("(\\D*\\d){0,5}\\D*");

or:

boolean match = "A2sad..3f,3,sdasad2..2".matches("(\\D*\\d){5}\\D*");

and you don't need to add the "anchors" ^ and $ since Java's matches(...) already does a full match of the string.

Bart Kiers
I think this is what the author wants. He just wants to make sure there isn't _more_ than 5 digits.
reko_t
I'd change (\D*\d) to use non-capturing group though. It's a bit more faster (although it's almost negligible).
reko_t
@01, yes, that's why I said *"a max of 5 digit"*. If you need to match exactly 5 digits, replace `{0,5}` with `{5}`.
Bart Kiers
thanks, thats what i was looking for
01
@01, you're welcome.
Bart Kiers
@reko_t, yes, since it is most probably negligible, I omitted it in favour of readability.
Bart Kiers
+1  A: 

One way is to use negative look-ahead:

^(?!(?:\D*\d){6})
reko_t