diff --git a/src/lib/isFloat.js b/src/lib/isFloat.js index 84bdc782c..01ce6c9f1 100644 --- a/src/lib/isFloat.js +++ b/src/lib/isFloat.js @@ -2,10 +2,25 @@ import assertString from './util/assertString'; import isNullOrUndefined from './util/nullUndefinedCheck'; import { decimal } from './alpha'; +// The pattern only varies with the decimal separator, which comes from a fixed set of +// locales, so the compiled regexes are cached instead of being rebuilt on every call. +const floatRegexByDecimal = new Map(); + +function floatRegex(decimalSeparator) { + let regex = floatRegexByDecimal.get(decimalSeparator); + + if (!regex) { + regex = new RegExp(`^(?:[-+])?(?:[0-9]+)?(?:\\${decimalSeparator}[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$`); + floatRegexByDecimal.set(decimalSeparator, regex); + } + + return regex; +} + export default function isFloat(str, options) { assertString(str); options = options || {}; - const float = new RegExp(`^(?:[-+])?(?:[0-9]+)?(?:\\${options.locale ? decimal[options.locale] : '.'}[0-9]*)?(?:[eE][\\+\\-]?(?:[0-9]+))?$`); + const float = floatRegex(options.locale ? decimal[options.locale] : '.'); if (str === '' || str === '.' || str === ',' || str === '-' || str === '+') { return false; }