Исправить номер телефона по шаблону regexp на python
Появилась потребность исправлять номер телефона по регулярному выражению. на вход подают номер телефона (например +79991112233) и маску к которой надо привести номер:
mask="^(\\d{10})$" надо получить 9991112233
mask="^\\((\\d{3})\\)(\\d{3})\\-(\\d{2})\\-(\\d{2})$" надо получить (999)111-22-33
номер который дают привожу к 10 цифрам так:
phone = [digit for digit in phone_number if digit.isdigit()][1:]
а как дальше из этого сделать номер по переданной маске?
Как посоветовал @Алексей Р, сделал универсальную входную маску и пытаюсь сгенерировать выходную по маске, получилось как-то очень костыльно:
mask = "+7(<!^\\d{0,3}$>)<!^\\d{0,3}$>-<!^\\d{0,2}$>-<!^\\d{0,2}$>"
# mask = "+7<!^\\d{0,10}$>"
phone = "9991112233"
res = []
start = r"<!^\d{0,"
end = r"}$>"
skip = 0
replace = False
group = 1
for i, st in enumerate(mask):
if mask.find(start, i, i + len(start)) != -1:
skip = len(start)
replace = True
if mask.find(end, i, i + len(end)) != -1:
skip = len(end)
if skip > 0:
skip -= 1
continue
if replace:
for _ in range(int(mask[i: mask.find(end, i)])):
res.append(f"\\{group}")
group += 1
replace = False
skip = 1
else:
res.append(st)
out_mask = "".join(res)
result = re.sub(r"(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)", out_mask, phone)
print(result)
Мне это не очень нравится, может можно как-то более красиво переписать?
Ответы (2 шт):
Вариант, когда входной формат в точности не определен, но он является корректным, если содержит 11 цифр.
import re
numbers = ('+7 (999) 1-1-1-2233', '+7/ 999 /888 /77/ 66', '-51254', '+7123457894455214', '+79991234567')
in_mask = r'(\d)' * 10
out_masks = (r'(\1\2\3)\4\5\6-\7\8-\9\10', r'\1\2\3\4\5\6\7\8\9\10', r'+7 \1\2\3 \4\5\6\7-\8\9\10')
for n in numbers:
phone = ''.join([digit for digit in n if digit.isdigit()][1:])
if len(phone) == 10:
for m in out_masks:
print(re.sub(in_mask, m, phone))
else:
print(f'Номер {n} не соответствует входной маске')
(999)111-22-33
9991112233
+7 999 1112-233
(999)888-77-66
9998887766
+7 999 8887-766
Номер -51254 не соответствует входной маске
Номер +7123457894455214 не соответствует входной маске
(999)123-45-67
9991234567
+7 999 1234-567
решил следующим способом, правим номер телефона под маску которую нам дали:
import re
def tel_format(phone, mask):
block_reg_exp = "<!.*?>"
while True:
found_block = re.search(block_reg_exp, mask)
if found_block is None:
break
block = found_block.group(0)
temporary_mask = "#" * int(re.search(r",\d+", block).group(0)[1:])
mask = mask.replace(found_block.group(0), temporary_mask)
phone = [digit for digit in phone if digit.isdigit()][1:]
phone_mask = list(mask)
for i, elem in enumerate(phone_mask):
if elem == "#":
phone_mask[i] = phone.pop(0)
return "".join(phone_mask)
assert tel_format("79998887766", "(<!^\\d{0,3}$>)<!^\\d{0,3}$>-<!^\\d{0,2}$>-<!^\\d{0,2}$>") == "(999)888-77-66"
assert tel_format("79998887766", "+7(<!^\\d{0,3}$>)<!^\\d{0,7}$>") == "+7(999)8887766"
assert tel_format("79998887766", "<!^\\d{0,10}$>") == "9998887766"
assert tel_format("79998887766", "+7-<!^\\d{0,3}$>-<!^\\d{0,3}$>-<!^\\d{0,2}$>-<!^\\d{0,2}$>") == "+7-999-888-77-66"
assert tel_format("+7-999-888-77-66", "(<!^\\d{0,3}$>)<!^\\d{0,3}$>-<!^\\d{0,1}$>-<!^\\d{0,1}$>-<!^\\d{0,1}$>-<!^\\d{0,1}$>") == "(999)888-7-7-6-6"
assert tel_format("+7(999)888-77-66", "+7<!^\\d{0,10}$>") == "+79998887766"
assert tel_format("+7(999)8887766", "<!^\\d{0,10}$>") == "9998887766"