DevCentraler Mike posted a question today about the best way to approach normalizing phone numbers from Active Directory. Turns out not everyone is a an of normalizing them all in AD, so Mike reached out for suggestions. Regex is always a popular go-to tool for tasks like this, but that's rarely the best approach in iRules.  Basically, the phone number can exist in many forms when it's slurped in for evaluation

  • 123.456.7890
  • 123-456-7890
  • 123 456 7890
  • (123) 456-7890

And on, and on. Current King of the Hill and F5er Kevin replied back with a snazzy and incredibly simple string map. Rather than move everything to a standard format with dashes, dots, parantheses, or some combination of some or all of the above, Kevin's solution just removes them all and just focuses on the numbers themselves. Again, super simple:

set num1 "123.456.7890"
set num2 "123-456-7890"
set num3 "123 456 7890"
set num4 "(123) 456-7890"

log local0. [string map {"." "" " " "" "-" "" "(" "" ")" ""} $num1]
log local0. [string map {"." "" " " "" "-" "" "(" "" ")" ""} $num2]
log local0. [string map {"." "" " " "" "-" "" "(" "" ")" ""} $num3]
log local0. [string map {"." "" " " "" "-" "" "(" "" ")" ""} $num4]

#output
    1234567890
    1234567890
    1234567890
    1234567890

The string map is basically just looking for the dot, the space, the dash, or the parentheses and mapping it to a null character. Pretty slick. I had another solution I cooked up as well, that also removes the non-numeric characters, but will do it for all non-numeric characters, not just the ones specified:

%proc justNumbers {pn} {
  set nums "0 1 2 3 4 5 6 7 8 9"
  set newNumber ""
  foreach x [split $pn ""] {
    if { !([lsearch $nums $x] == -1) } {
      append newNumber $x
    }
  }
  return $newNumber
}
% set x1 "1-800-632-6223"
1-800-632-6223
% set x2 "1.800.632.6223"
1.800.632.6223
% set x3 "1(800)632-6223"
1(800)632-6223
% justNumbers $x1
18006326223
% justNumbers $x2
18006326223
% justNumbers $x3
18006326223

Both work, just different approaches. Kevin's approach, however, is fast. Very fast.

% time { string map {"." "" " " "" "-" "" "(" "" ")" ""} $x3 } 100000
1.10809 microseconds per iteration
% time { justNumbers $x3 } 100000
9.95664 microseconds per iteration

Like nearly 89% faster! So if you have a specific list of characters to remove from a string, phone number or otherwise, string map is your baby. But if they are unknown, the proc approach is there for the taking.

Check out the original Q&A discussion, and make sure you vote up Mike's question and Kevin's spectacular response.