答案很大程度上取决于“数字字符串”的含义。如果您对数字字符串的定义是“浮点接受的任何内容”,那么很难改进 try-except 方法。
但请记住,float 可能比您想要的更自由:在大多数机器上,它会接受代表无穷大和 nans 的字符串。例如,在我的机器上,它接受'nan(dead!$#parrot)'
. 它还将接受前导和尾随空格。根据您的应用程序,您可能希望排除浮点数的指数表示。在这些情况下,使用正则表达式是有意义的。要仅排除无穷大和 nan,使用 try-except 方法然后使用 math.isnan 和 math.isinf 检查转换结果可能会更快。
为数字字符串编写正确的正则表达式是一项非常容易出错的任务。例如,您的IsNumber2
函数接受字符串'.'
。您可以在十进制模块源中找到经过实战测试的数字字符串正则表达式版本。这是(有一些小的编辑):
_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 接受的内容,除了前导和尾随空格以及 nans 的一些细微差异(用于信号 nans 的额外 's' 和诊断信息)。当我需要一个数字正则表达式时,我通常从这个开始并编辑掉我不需要的位。
注意可以想象,浮点数可能比正则表达式慢,因为它不仅要解析字符串,还要将其转换为浮点数,这是一个相当复杂的计算;但是,如果是这样,那仍然会令人惊讶。