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'}