Ответ во многом зависит от того, что вы подразумеваете под «числовой строкой». Если вы определили числовую строку как «все, что может принимать float», то трудно улучшить метод try-exc.
Но имейте в виду, что float может быть более либеральным, чем вы хотите: на большинстве машин он принимает строки, представляющие бесконечность и nans. На моей машине он принимает 'nan(dead!$#parrot)'
, например. Он также будет принимать начальные и конечные пробелы. И в зависимости от вашего приложения вы можете исключить экспоненциальное представление чисел с плавающей точкой. В этих случаях использование регулярных выражений имело бы смысл. Чтобы просто исключить бесконечности и nans, может быть быстрее использовать метод try-exc, а затем использовать 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 (дополнительные 's' для сигнализации nans и диагностическая информация). Когда мне нужно числовое регулярное выражение, я обычно начинаю с этого и редактирую ненужные мне биты.
N.B. возможно , что float может быть медленнее, чем регулярное выражение, поскольку он должен не только анализировать строку, но и превращать ее в float, что является довольно сложным вычислением; все же было бы сюрпризом, если бы это было так.