答えは、「数値文字列」の意味に大きく依存します。数値文字列の定義が「float が受け入れるものすべて」である場合、try-except メソッドを改善することは困難です。
ただし、float は必要以上にリベラルである可能性があることに注意してください。ほとんどのマシンでは、無限大と nan を表す文字列を受け入れます。'nan(dead!$#parrot)'
私のマシンでは、たとえば受け入れます。また、先頭と末尾の空白も受け入れます。アプリケーションによっては、float の指数表現を除外したい場合があります。このような場合、正規表現を使用することは理にかなっています。無限大と nan のみを除外するには、try-except メソッドを使用してから、math.isnan と math.isinf を使用して変換の結果を確認する方が速い場合があります。
数値文字列の正しい正規表現を作成することは、驚くほどエラーが発生しやすい作業です。たとえば、IsNumber2
関数は string を受け入れます'.'
。decimal モジュールのソースで、数値文字列の正規表現の実戦でテストされたバージョンを見つけることができます。これは次のとおりです(いくつかのマイナーな編集があります):
_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
これは float が受け入れるものとほとんど一致しますが、先頭と末尾の空白と nan のわずかな違い (nan を通知するための余分な 's' と診断情報) を除きます。数値の正規表現が必要な場合、通常はこの正規表現から始めて、不要な部分を編集します。
NB float は、文字列を解析するだけでなく、かなり複雑な計算である float に変換する必要があるため、正規表現よりも遅くなる可能性があると考えられます。しかし、それがあったとしても、それはまだ驚くべきことです.