Регулярная валюта Python 3.5 - PullRequest
       11

Регулярная валюта Python 3.5

0 голосов
/ 23 ноября 2018

Я пытаюсь переформатировать валюту евро в текстовые данные.Исходный формат выглядит следующим образом: 3 000,00 евро или также 33 540 000 евро. -.
Я хочу стандартизировать формат до 3000,00 евро или 33540000,00 евро.
Я переформатировал 2,500 евро - успешно используя этот код:

import re
format1 = "a piece of text with currency EUR 2.500.- and some other information"
regexObj = re.compile(r'EUR\s*\d{1,3}[.](\d{3}[.]-)')
text1 = regexObj.sub(lambda m:"\u20ac"+"{:0.2f}".format(float(re.compile('\d+(.\d+)?(\.\d+)?').search(m.group().replace('.','')).group())),format1)
Out: "a piece of text with currency €2500.00 and some other information"

Это дает мне € 2500,00, что правильно.Я пытался применить ту же логику к другим форматам безрезультатно.

format2 = "another piece of text EUR 3.000.00 and EUR 5.000.00. New sentence"
regexObj = re.compile('\d{1,3}[.](\d{3}[.])(\d{2})?')
text2 = regexObj.sub(lambda m:"\u20ac"+"{:0.2f}".format(float(re.compile('\d+(.\d+)?(\.\d+)?').search(m.group().replace('.','')).group())),format2)
Out: "another piece of text EUR €300000.00 and EUR €500000.00. New sentence"

и

format3 = "another piece of text EUR 33.540.000.- and more text"
regexObj = regexObj = re.compile(r'EUR\s*\d{1,3}[.](\d{3}[.])(\d{3}[.])(\d{3}[.]-)')
text3 = regexObj.sub(lambda m:"\u20ac"+"{:0.2f}".format(float(re.compile('\d+(.\d+)?(.\d+)?').search(m.group().replace('.','')).group())),format3)
Out: "another piece of text EUR 33.540.000.- and more text"

Я думаю, что проблема может быть в regexObj.sub (), так как часть .format () меня смущает.Я пытался изменить re.compile ('\ d + (. \ D +)? (. \ D +)?') В этом, но я не могу создать желаемый результат.Любые идеи высоко ценится.Спасибо!

1 Ответ

0 голосов
/ 23 ноября 2018

Давайте начнем с регулярного выражения.Мои предложения:

EUR\s*(?:(\d{1,3}(?:\.\d{3})*)\.-|(\d{1,3}(?:\.\d{3})*)(\.\d{2}))

Детали:

  • EUR\s* - Начальная часть.
  • (?: - Начало группы без захвата -контейнер для альтернатив.
  • ( - начало группы захвата # 1 (целая часть с ".-" вместо десятичной части).
  • \d{1,3} - до 3цифры.
  • (?:\.\d{3})* - часть ".ddd", 0 или более раз.
  • ) - конец группы # 1.
  • \.- - ".- "окончание.
  • | - альтернативный разделитель.
  • ( - запуск группы захвата # 2 (целочисленная часть)
  • \d{1,3}(?:\.\d{3})* - лайкв альтернативе 1.
  • ) - конец группы № 2.
  • (\.\d{2}) - группа захвата № 3 (точка и десятичная часть).
  • )- Конец группы без захвата.

Вместо лямбда-функции я использовал «обычную» функцию репликации, я назвал ее repl.Он содержит 2 части, для группы 1 и группы 2 + 3.

В обоих вариантах удаляются точки из целочисленной части, но «последняя» точка (после целой части) является частью группы 3,поэтому он не удаляется.

Таким образом, весь сценарий может выглядеть следующим образом:

import re

def repl(m):
    g1 = m.group(1)
    if g1:   # Alternative 1: ".-" instead of decimal part
        res = g1.replace('.','') + '.00'
    else:    # Alternative 2: integet part (group 2) + decimal part (group 3)
        res = m.group(2).replace('.','') + m.group(3)
    return "\u20ac" + res

# Source string
src = 'xxx EUR 33.540.000.- yyyy EUR 3.000.00 zzzz EUR 5.210.15 vvvv'
# Regex
pat = re.compile(r'EUR\s*(?:(\d{1,3}(?:\.\d{3})*)\.-|(\d{1,3}(?:\.\d{3})*)(\.\d{2}))')
# Replace
result = pat.sub(repl, src)

Результат:

xxx €33540000.00 yyyy €3000.00 zzzz €5210.15 vvvv

Как видите, не нужноиспользовать float или format.

...