Your ".*"
patterns are being greedy, as is their wont, and are gobbling up as much as they can -- which is going to be the entire string. So that first ".*"
is matching the entire string, rendering the rest moot. Also, your "\\d?"
clauses indicate a single digit which happens to be optional, neither of which is what you want.
This is probably more in line with what you're shooting for:
Pattern stringWith2Numbers = Pattern.compile(".*?(\\d+).*?(\\d+).*?");
Of course, since you don't really care about the stuff before or after the numbers, why bother with them?
Pattern stringWith2Numbers = Pattern.compile("(\\d+).*?(\\d+)");
That ought to do the trick.
Edit: Taking time out from writing butt-kickingly awesome comics, Alan Moore pointed out some problems with my solution in the comments. For starters, if you have only a single multi-digit number in the string, my solution gets it wrong. Applying it to "This 123 is a bad string" would cause it to return "12" and "3" when it ought to simply fail. A better regex would stipulate that there MUST be at least one non-digit character separating the two numbers, like so:
Pattern stringWith2Numbers = Pattern.compile("(\\d+)\\D+(\\d+)");
Also, matches()
applies the pattern to the entire string, essentially bracketing it in ^
and $
; find()
would do the trick, but that's not what the OP was using. So sticking with matches()
, we'd need to bring back in those "useless" clauses in front of and after the two numbers. (Though having them explicitly match non-digits instead of the wildcard is better form.) So it would look like:
Pattern stringWith2Numbers = Pattern.compile("\\D*(\\d+)\\D+(\\d+)\\D*");
... which, it must be noted, is damn near identical to jjnguy's answer.