import re from string import digits PHONE_RE = re.compile('([(]{0,1}[2-9]d{2}[)]{0,1}[-_. ]{0,1}[2-9]d{2}[-_. ]{0,1}d{4})') def numbers2links(s): result = "" last_match_index = 0 for match in PHONE_RE.finditer(s): raw_number = match.group() number = ''.join(d for d in raw_number if d in digits) call = '%s' % (number, raw_number) result += s[last_match_index:match.start()] + call last_match_index = match.end() result += s[last_match_index:] return result >>> numbers2links("Ghost Busters at (555) 423-2368! How about this one: 555 456 7890! 555-456-7893 is where its at.") 'Ghost Busters at (555) 423-2368! How about this one: 555 456 7890! 555-456-7893 is where its at.' import re PHONE_RE = re.compile('([(]{0,1}[2-9]d{2}[)]{0,1}[-_. ]{0,1}[2-9]d{2}[-_. ]{0,1}d{4})') NON_NUMERIC = re.compile('D') def numbers2links(s): def makelink(mo): raw_number = mo.group() number = NON_NUMERIC.sub("", raw_number) return '%s' % (number, raw_number) return PHONE_RE.sub(makelink, s) print numbers2links("Ghost Busters at (555) 423-2368! How about this one: 555 456 7890! 555-456-7893 is where its at.") ((00|+)?1[. -]?)?(?[2-9][0-8][0-9])?[. -]?[2-9](00|[2-9]{2})[. -]?(?!0{4})d{4}([. -]?[x#-]d+)? | A |S | | B | S | C | S | D | S | E |