Как извлечь плавающее число из строки [дубликат]
этот вопрос уже есть ответ здесь:
- Извлеките поплавок / двойное значение 4 ответы
У меня есть несколько строк, похожих на Current Level: 13.4 db.
и я хочу извлечь только число с плавающей запятой. Я говорю плавающий, а не десятичный, как это иногда бывает целым. Может ли регулярное выражение сделать это или есть лучший способ?
7 ответов:
Если ваш float всегда выражается в десятичной нотации что-то вроде
>>> import re >>> re.findall("\d+\.\d+", "Current Level: 13.4 db.") ['13.4']
может быть достаточно.
более надежная версия будет:
>>> re.findall(r"[-+]?\d*\.\d+|\d+", "Current Level: -13.2 db or 14.2 or 3") ['-13.2', '14.2', '3']
Если вы хотите проверить ввод пользователя, вы можете также проверить наличие поплавка, перейдя к нему напрямую:
user_input = "Current Level: 1e100 db" for token in user_input.split(): try: # if this succeeds, you have your (first) float print float(token), "is a float" except ValueError: print token, "is something else" # => Would print ... # # Current is something else # Level: is something else # 1e+100 is a float # db is something else
вы можете попробовать что-то вроде этого, которое охватывает все базы, в том числе не полагаясь на пробелы после числа:
>>> import re >>> numeric_const_pattern = r""" ... [-+]? # optional sign ... (?: ... (?: \d* \. \d+ ) # .1 .12 .123 etc 9.1 etc 98.1 etc ... | ... (?: \d+ \.? ) # 1. 12. 123. etc 1 12 123 etc ... ) ... # followed by optional exponent part if desired ... (?: [Ee] [+-]? \d+ ) ? ... """ >>> rx = re.compile(numeric_const_pattern, re.VERBOSE) >>> rx.findall(".1 .12 9.1 98.1 1. 12. 1 12") ['.1', '.12', '9.1', '98.1', '1.', '12.', '1', '12'] >>> rx.findall("-1 +1 2e9 +2E+09 -2e-9") ['-1', '+1', '2e9', '+2E+09', '-2e-9'] >>> rx.findall("current level: -2.03e+99db") ['-2.03e+99'] >>>
для легкого копирования вставки:
numeric_const_pattern = '[-+]? (?: (?: \d* \. \d+ ) | (?: \d+ \.? ) )(?: [Ee] [+-]? \d+ ) ?' rx = re.compile(numeric_const_pattern, re.VERBOSE) rx.findall("Some example: Jr. it. was .23 between 2.3 and 42.31 seconds")
Python docs имеет ответ, который охватывает +/ -, и показатель степени нотации
scanf() Token Regular Expression %e, %E, %f, %g [-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)? %i [-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)
это регулярное выражение не поддерживает международные форматы, где запятая используется как разделитель между целой и дробной частью (3,14159). В этом случае, замените все
\.
С[.,]
В приведенном выше регулярном выражении с плавающей точкой.Regular Expression International float [-+]?(\d+([.,]\d*)?|[.,]\d+)([eE][-+]?\d+)?
re.findall(r"[-+]?\d*\.\d+|\d+", "Current Level: -13.2 db or 14.2 or 3")
как описано выше, работает очень хорошо! Одно предложение:
re.findall(r"[-+]?\d*\.\d+|[-+]?\d+", "Current Level: -13.2 db or 14.2 or 3 or -3")
также вернет отрицательные значения int (например, -3 В конце этой строки)
вы можете использовать следующее регулярное выражение для получения целых и плавающих значений из строки:
re.findall(r'[\d\.\d]+', 'hello -34 42 +34.478m 88 cricket -44.3') ['34', '42', '34.478', '88', '44.3']
спасибо Рекс
Я думаю, что вы найдете интересные вещи в следующем моем ответе, который я сделал для предыдущего аналогичного вопроса:
https://stackoverflow.com/q/5929469/551449
в этом ответе я предложил шаблон, который позволяет регулярному выражению поймать любое число, и поскольку мне больше нечего добавить к нему, я думаю, что он довольно полный
другой подход, который может быть более читабельным простое преобразование типов. Я добавил функцию замены для покрытия случаев, когда люди могут вводить европейские десятичные числа:
>>> for possibility in "Current Level: -13.2 db or 14,2 or 3".split(): ... try: ... str(float(possibility.replace(',', '.'))) ... except ValueError: ... pass '-13.2' '14.2' '3.0'
это тоже имеет недостатки. Если кто-то наберет "1,000", это будет преобразовано в 1. Кроме того, он предполагает, что люди будут вводить пробелы между словами. Это не относится к другим языкам, таким как китайский.