I\'ve got a DB chock full o\' phone numbers as strings, they\'re all formatted like 1112223333, I\'d like to display it as 111-222-3333 in my django template
I know
Just one other solution:
n.phone = "%c%c%c-%c%c%c-%c%c%c%c" % tuple(map(ord, n.phone))
or
n.phone = "%s%s%s-%s%s%s-%s%s%s%s" % tuple(n.phone)
def formatPhone(phone):
formatted = ''
i = 0
# clean phone. skip not digits
phone = ''.join(x for x in phone if x.isdigit())
# set pattern
if len(phone) > 10:
pattern = 'X (XXX) XXX-XX-XX'
else:
pattern = 'XXX-XXX-XX-XX'
# reverse
phone = phone[::-1]
pattern = pattern[::-1]
# scan pattern
for p in pattern:
if i >= len(phone):
break
# skip non X
if p != 'X':
formatted += p
continue
# add phone digit
formatted += phone[i]
i += 1
# reverse again
formatted = formatted[::-1]
return formatted
print formatPhone('+7-111-222-33-44')
7 (111) 222-33-44
print formatPhone('222-33-44')
222-33-44
print formatPhone('23344')
2-33-44
Since we're speaking Pythonic :), it's a good habit to always use join instead of addition (+) to join strings:
phone = n.phone
n.phone = '-'.join((phone[:3],phone[3:6],phone[6:]))
This is quite a bit belated, but I figured I'd post my solution anyway. It's super simple and takes advantage of creating your own template tags (for use throughout your project). The other part of this is using the parenthesis around the area code.
from django import template
register = template.Library()
def phonenumber(value):
phone = '(%s) %s - %s' %(value[0:3],value[3:6],value[6:10])
return phone
register.filter('phonenumber', phonenumber)
For the rest of your project, all you need to do is {{ var|phonenumber }}
It may be overkill for your use case if all your numbers are formatted the same way, but you might consider using the phonenumbers module. It would allow you to add functionality (e.g. international phone numbers, different formatting, etc) very easily.
You can parse your numbers like this:
>>> import phonenumbers
>>> parsed_number = phonenumbers.parse('1112223333', 'US')
>>> parsed_number
PhoneNumber(country_code=1, national_number=1112223333L, extension=None, italian_leading_zero=False, country_code_source=None, preferred_domestic_carrier_code=None)
Then, to format it the way you want, you could do this:
>>> phonenumbers.format_number(parsed_number, phonenumbers.PhoneNumber())
u'111-222-3333'
Note that you could easily use other formats:
>>> phonenumbers.format_number(parsed_number, phonenumbers.PhoneNumberFormat.NATIONAL)
u'(111) 222-3333'
>>> phonenumbers.format_number(parsed_number, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
u'+1 111-222-3333'
>>> phonenumbers.format_number(parsed_number, phonenumbers.PhoneNumberFormat.E164)
u'+11112223333'