I need to convert a string in the format \"1.234.345,00\" to the float value 1234345.00.
One way is to use repeated str.repl
Here's something, using Babel, that works for me.
First you feed it some test data, with your expectations and it builds a dictionary of separator to locale alias that fits.
Then you can convert from that point on.
import string
from decimal import Decimal
from babel.numbers import parse_decimal, NumberFormatError
from babel.core import UnknownLocaleError
import locale
traindata = [
("1.234.345,00", Decimal("1234345.00")),
("1,234,345.00", Decimal("1234345.00")),
("345", Decimal("345.00")),
]
data = traindata + [
("345,00", Decimal("345.00")),
("345.00", Decimal("345.00")),
("746", Decimal("746.00")),
]
def findseps(input_):
#you need to have no separator
#or at least a decimal separator for this to work...
seps = [c for c in input_ if not c in string.digits]
if not seps:
return ""
sep = seps[-1]
#if the decimal is something then thousand will be the other...
seps = "." + sep if sep == "," else "," + sep
return seps
def setup(input_, exp, lookup):
key = findseps(input_)
if key in lookup:
return
for alias in locale.locale_alias:
#print(alias)
try:
got = parse_decimal(input_, locale=alias)
except (NumberFormatError,UnknownLocaleError, ValueError) as e:
continue
except (Exception,) as e:
raise
if exp == got:
lookup[key] = alias
return
def convert(input_, lookup):
seps = findseps(input_)
try:
locale_ = lookup[seps]
convert.locale_ = locale_
except (KeyError,) as e:
convert.locale_ = None
return "unexpected seps:%s" % seps
try:
return parse_decimal(input_, locale=locale_)
except (Exception,) as e:
return e
lookup = {}
#train your data
for input_, exp in traindata:
setup(input_, exp, lookup)
#once it's trained you know which locales to use
print(data)
for input_, exp in data:
got = convert(input_, lookup)
# print (input_)
msg = "%s => %s with local:%s:" % (input_, got, convert.locale_)
if exp == got:
print("\n success : " + msg)
else:
print("\n failure : " + msg)
print(lookup)
output:
[('1.234.345,00', Decimal('1234345.00')), ('1,234,345.00', Decimal('1234345.00')), ('345', Decimal('345.00')), ('345,00', Decimal('345.00')), ('345.00', Decimal('345.00')), ('746', Decimal('746.00'))]
success : 1.234.345,00 => 1234345.00 with local:is_is:
success : 1,234,345.00 => 1234345.00 with local:ko_kr.euc:
success : 345 => 345 with local:ko_kr.euc:
success : 345,00 => 345.00 with local:is_is:
success : 345.00 => 345.00 with local:ko_kr.euc:
success : 746 => 746 with local:ko_kr.euc:
{',.': 'ko_kr.euc', '': 'ko_kr.euc', '.,': 'is_is'}