The answer depends a lot on what you mean by 'numeric string'. If your definition of numeric string is 'anything that float accepts', then it's difficult to improve on the try-except method.
But bear in mind that float may be more liberal than you want it to be: on most machines, it'll accept strings representing infinities and nans. On my machine, it accepts 'nan(dead!$#parrot)'
, for example. It will also accept leading and trailing whitespace. And depending on your application, you may want to exclude exponential representations of floats. In these cases, using a regex would make sense. To just exclude infinities and nans, it might be quicker to use the try-except method and then use math.isnan and math.isinf to check the result of the conversion.
Writing a correct regex for numeric strings is a surprisingly error-prone task. Your IsNumber2
function accepts the string '.'
, for example. You can find a battle-tested version of a numeric-string regex in the decimal module source. Here it is (with some minor edits):
_parser = re.compile(r""" # A numeric string consists of:
(?P<sign>[-+])? # an optional sign, followed by either...
(
(?=\d|\.\d) # ...a number (with at least one digit)
(?P<int>\d*) # having a (possibly empty) integer part
(\.(?P<frac>\d*))? # followed by an optional fractional part
(E(?P<exp>[-+]?\d+))? # followed by an optional exponent, or...
|
Inf(inity)? # ...an infinity, or...
|
(?P<signal>s)? # ...an (optionally signaling)
NaN # NaN
(?P<diag>\d*) # with (possibly empty) diagnostic info.
)
\Z
""", re.VERBOSE | re.IGNORECASE | re.UNICODE).match
This pretty much matches exactly what float accepts, except for the leading and trailing whitespace and some slight differences for nans (the extra 's' for signaling nans, and the diagnostic info). When I need a numeric regex, I usually start with this one and edit out the bits I don't need.
N.B. It's conceivable that float could be slower than a regex, since it not only has to parse the string, but also turn it into a float, which is quite an involved computation; it would still be a surprise if it were, though.