international phone number validator
W-Mark Kubacki <public-/[email protected]>
| Newsgroups | gmane.comp.python.formencode |
|---|---|
| Message-ID | <[email protected]> |
Hello group, I'd like to share my (international) phone number validator with you. Please see the attachment. Of course, any feedback is welcome. I've already offered it Ian Bicking, but he didn't answer me whether he liked it or whether it gets integrated. As one cannot tell the US phone number 393-555-3939 from a (e.g.,) german one, those formats are not accepted by the validator. Es grüßt W-Mark Kubacki ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ FormEncode-discuss mailing list FormEncode-discuss-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/formencode-discuss
IPhoneNumberValidator.py
(text/plain, 3.7 KB)
import re
import string
from gettext import gettext as _
from formencode.api import FancyValidator
from formencode.validators import Invalid
# from dbmanager.intl_util.validators@r313[208:303]
class IPhoneNumberValidator(FancyValidator):
"""
Validates, and converts phone numbers to +##-###-#######.
Adapted from RFC 3966
::
>>> p = IPhoneNumberValidator()
>>> p.to_python('333-3333')
Traceback (most recent call last):
...
Invalid: Please enter a number, with area code, in the form +##-###-#######.
>>> p.to_python('0555/4860-300')
'+49-555-4860-300'
>>> p.to_python('0555-49924-51')
'+49-555-49924-51'
>>> p.to_python('0555/8114100')
'+49-555-8114100'
>>> p.to_python('0555 8114100')
'+49-555-8114100'
>>> p.to_python(' +49 (0)555 350 60 0')
'+49-555-35060-0'
>>> p.to_python('+49 555 350600')
'+49-555-350600'
>>> p.to_python('0049/ 555/ 871 82 96')
'+49-555-87182-96'
>>> p.to_python('0555-2 50-30')
'+49-555-250-30'
>>> p.to_python('(05 55)4 94 33 47')
'+49-555-49433-47'
>>> p.to_python('+973-555431')
'+973-555431'
>>> p.to_python('1-393-555-3939')
'+1-393-555-3939'
>>> p.to_python('+43 (1) 55528/0')
'+43-1-55528-0'
>>> p.to_python('+43 5555 429 62-0')
'+43-5555-42962-0'
>>> p.to_python('00 218 55 33 50 317 321')
'+218-55-3350317-321'
>>> p.to_python('+218 (0)55-3636639/38')
'+218-55-3636639-38'
"""
strip = True
default_cc = 49
_mark_translation = string.maketrans("_.!~*'/", "-------")
_preTransformations = [
(re.compile(r'^\((\d+)\s*(\d+)\)(.+)$'), '%s%s-%s'),
(re.compile(r'^(?:1-)(\d+.+)$'), '+1-%s'),
(re.compile(r'^00\s*(\d+.+)$'), '+%s'),
(re.compile(r'^(\+\d+)\s+\(0\)\s*(\d+.+)$'), '%s-%s'),
(re.compile(r'^(0\d+)\s(\d+)$'), '%s-%s'),
]
_ccIncluder = [
(re.compile(r'^0([1-9]\d*)\-(\d+.*)$'), '+%d-%s-%s'),
]
_postTransformations = [
(re.compile(r'^(\+\d+)[-\s]\(?(\d+)\)?[-\s](\d+.+)$'), '%s-%s-%s'),
(re.compile(r'^(.+)\s(\d+)$'), '%s-%s'),
]
_phoneIsSane = re.compile(r'^(\+[1-9]\d*)-([\d\-]+)$')
messages = {
'phoneFormat': _('Please enter a number, with area code, in the form +##-###-#######.'),
}
def _perform_rex_transformation(self, value, transformations):
for rex, trf in transformations:
match = rex.search(value)
if match:
value = trf % match.groups()
return value
def _prepend_country_code(self, value, transformations, country_code):
for rex, trf in transformations:
match = rex.search(value)
if match:
return trf % ((country_code,)+match.groups())
return value
def _to_python(self, value, state):
self.assert_string(value, state)
value = self._perform_rex_transformation(value, self._preTransformations)
value = value.translate(self._mark_translation)
value = self._prepend_country_code(value, self._ccIncluder, self.default_cc)
for f, t in [(' ', ' '), ('--', '-'), (' - ', '-'), ('- ', '-'), (' -', '-')]:
value = value.replace(f, t)
value = self._perform_rex_transformation(value, self._postTransformations)
value = value.replace(' ', '')
# did we successfully transform that phone number? Thus, is it valid?
if not self._phoneIsSane.search(value):
raise Invalid(self.message('phoneFormat', state), value, state)
return value