Это, кажется, работает очень хорошо: r'(\d{,3})?[.,]?(\d{3})?'
. Тестирование:
import re
pattern = r'(\d{,3})?[.,]?(\d{3})?'
tests = ['1,234.50',
'456.7',
'12']
for t in tests:
print(''.join([g for g in re.match(pattern, t).groups() if g is not None]))
# 1234
# 456
# 12
К сожалению, вы столкнулись с проблемой повторных группировок. Похоже, что пакет re
не поддерживает повторный захват подгрупп. В этих случаях вам, вероятно, следует использовать строку replace.
Разбиваем регулярное выражение:
pattern = """ ( # begin capture group
\d{,3} # up to three digits
) # end capture group
? # zero or one of these first groups of digits
[.,]? # zero or one period or comma (not captured)
( # begin capture group inside of the non-capture group
\d{3} # exactly three digits
) # end capture group
? # zero or one of these
"""
Возможно, вы могли бы немного упростить это, но главное, что вы захватываете каждую группу из трех цифр (обрабатывает первую по-разному, потому что она может быть до трех), разделенных необязательными запятыми. Чтобы собрать их все вместе, просто используйте ''.join([g for g in re.match(pattern, my_string).groups() if g is not None])
, как в примере кода.