Я не думаю, что исключение (даже если оно срабатывает) намного дороже, чем регулярное выражение - вам придется профилировать его и посмотреть, действительно ли оно имеет значение.
Тем не менее, регулярное выражение, которое реализует грамматику BigDecimal в соответствии с Java Docs , равно
[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?
Пояснение:
[+-]? # optional sign
(?: # required significand: either...
\d+ # a number
(?:\.\d*)? # optionally followed by a dot, optionally followed by more digits
| # or...
\.\d+ # just a dot, followed by digits (in this case required)
) # end of significand
(?: # optional exponent
[eE] # required exponent indicator
[+-]? # optional sign
\d+ # required digits
)? # end of exponent
Если вы хотите разрешить разные числовые форматы (и разделители тысяч), вы можете сначала получить эти значения из DecimalFormatSymbols
и построить с ним свое регулярное выражение.
Примерно так (я не знаю Java, поэтому не стесняйтесь исправлять мои синтаксические ошибки):
// you need java.util.regex.Pattern and java.text.DecimalFormatSymbols
string ds = Pattern.quote(DecimalFormatSymbols.getDecimalSeparator())
string gs = Pattern.quote(DecimalFormatSymbols.getGroupingSeparator())
string ms = Pattern.quote(DecimalFormatSymbols.getMinusSign())
string es = Pattern.quote(DecimalFormatSymbols.getExponentSeparator())
string myre =
"(?xi)\n # verbose, case-insensitive regex" +
"[+" +ms+ "]? # optional sign\n" +
"(?: # required significand: either...\n" +
" (?:\\d{1,3}(?:" +gs+ "\\d{3}|\\d++) # a number with optional thousand separators,\n" +
" (?:" +ds+ "\\d*)? # optionally followed by a dot, optionally followed by more digits\n" +
" | # or...\n" +
ds+ "\\d+ # just a dot, followed by digits (in this case required)\n" +
") # end of significand\n" +
"(?: # optional exponent\n" +
es+ " # required exponent indicator\n" +
" [+" +ms+ "]? # optional sign\n" +
" \\d+ # required digits\n" +
")? # end of exponent"
boolean foundMatch = subjectString.matches(myregex);
Затем можно заменить биты, зависящие от локали, обратно в их аналоги в США, прежде чем передавать число для преобразования BigDecimal, если оно не учитывает локаль.