In order to satisfy both requirements, you would need something else than Double.parseDouble()
. For one, it will use the current locale; also, its error message won't be as detailed as you want to be.
A solution would be to go through a regex to parse the input string, and only if the regex passes, parse using a NumberFormat
:
private static final Pattern NUMPATTERN = Pattern.compile("\\d+([.,])\\d+");
// ...
// Supposes a custom MyException class
public double doParseDouble(final String input)
throws MyException
{
final Matcher m = NUMPATTERN.matcher(input);
if (!m.matches())
throw new MyException("Non number characters in input");
final String separator = m.group(1);
final Locale locale = ".".equals(separator)
? Locale.US : Locale.FRENCH;
final NumberFormat fmt = NumberFormat.getInstance(locale);
try {
return fmt.parse(input).doubleValue();
} catch (NumberFormatException e) {
throw new MyException(e);
}
}
This is only sample code and lacks a LOT of features:
- restricts to only a subset of valid
double
s (.1
will not be accepted for instance; or1.4e-3
); - does not deal with overflows/underflows;
- others.