Этот вид вещей часто выполняется путем повторения пучка регулярных выражений и остановки, когда вы находите тот, который соответствует - потому что ваше преобразование из строки в число требует специального анализа за пределами возможностей регулярных выражений. Это означает, что вам нужно заказать их так, как вы знаете, даст правильный ответ. В этом случае, вы можете сделать что-то вроде этого:
PARSERS = (
(re.compile(r'([0-9]+)\(([-+0-9.]+)[mM]\)'), 1000000),
(re.compile(r'([0-9]+)\(([-+0-9.]+)[kK]\)'), 1000),
(re.compile(r'([0-9]+)\(([-+0-9.]+)\)'), 1),
)
def parse(num):
for pattern, multiplier in PARSERS:
match = pattern.match(num)
if match is not None:
return float(match.group(1)), float(match.group(2)) * multiplier
raise ValueError("Failed to parse")
Как и в сторону, эта модель часто встречается в других местах тоже, например, решая which function will handle a web request на основе URL.
Просто для удовольствия, вот альтернативная реализация, которая использует словарь Lookups и регулярное выражение, вместо итерации:
MULTIPLIER = {
'M': 1000000,
'K': 1000,
'': 1,
}
PATTERN = re.compile(r'(\d+)\(([-+.\d]+)([kKmM]?)\)')
def parse(num):
match = PATTERN.match(num)
if match is None:
raise ValueError("Failed to parse")
first, second, suffix = match.groups()
suffix = suffix.upper()
if suffix not in MULTIPLIER:
raise ValueError("Unrecognised multiplier %s" % suffix)
return float(first), float(second) * MULTIPLIER[suffix]
'([0-9]) +' будет улавливать только последнюю цифру. Используйте '([0-9] +)'. Также '[0-9]' можно заменить на '\ d'. –
@ z0r: спасибо! просто, что я думал, что шансы на то, чтобы получить какой-либо ответ! – chapter3
@Alex: спасибо за оптимизацию! :) – chapter3