Skip to content

Instantly share code, notes, and snippets.

@dgmltn
Last active December 12, 2015 06:28
Show Gist options
  • Save dgmltn/4729109 to your computer and use it in GitHub Desktop.
Save dgmltn/4729109 to your computer and use it in GitHub Desktop.
iPhone Dialpad-like dynamic phone number formatter.
/**
* A semicolon separated list of formatting strings to format. "N"
* represents any single digit. [1-9()-] represents an exact digit. The
* underscore "_" represents a SPACE (not an underscore). These rules will
* be followed sequentially until one is matched.
*/
private static final String DIALPLAN = "+1_NNN_NNN_NNNN;1_(NNN)_NNN-NNNN;NNN-NNNN;(NNN)_NNN-NNNN";
/**
* Formats a phone number according to the rules defined in
* {@link #DIALPLAN}.
*
* @param number
* the non-formatted number
* @param isPartialOk
* true if the number passed in "number" are just the first few
* digits of the formatted number. This might be the case on a
* dialpad where the number is being inputted right now
* @return
*/
public static String formatDialplanNumber(String number, boolean isPartialOk) {
StringBuilder output = new StringBuilder(32);
/*
* k = index of "number" that we're trying to match d = index of
* "DIALPLAN" that we're trying to match cd = character of "DIALPLAN" at
* index "d" cn = character of "number" at index "k" ln = length of
* "number" match = does it match so far
*/
int k = 0;
boolean match = true;
int ln = number.length();
for (int d = 0; d < DIALPLAN.length(); d++) {
char cd = DIALPLAN.charAt(d);
char cn = k < ln ? number.charAt(k) : 0;
// move on to the next rule
if (cd == ';') {
if (match && k == ln)
break;
k = 0;
match = true;
if (output.length() > 0)
output.delete(0, output.length());
continue;
}
if (!match)
continue;
// next character in "number" must match exactly
if (cd == '+' || cd == '#' || cd == '*' || cd >= '0' && cd <= '9') {
if (k < ln && cn == cd) {
output.append(cd);
k++;
}
else {
match = false;
}
}
// next character in "number" must be a digit
else if (cd == 'N') {
if (k == ln) {
if (isPartialOk)
output.append(' ');
else
match = false;
} else if (cn >= '0' && cn <= '9') {
output.append(cn);
k++;
} else {
match = false;
}
}
// just add space to the output
else if (cd == '_') {
output.append(' ');
}
// just add the literal character to the output
else if (cd == '(' || cd == ')' || cd == '-' || cd == '.') {
output.append(cd);
}
}
if (!match || k != ln) {
// Didn't match anything... just rely on built-in phone number
// formatter
return PhoneNumberUtils.formatNumber(number);
}
// Remove non-numbers from the end of the string
int end = output.length();
int i = output.indexOf("( ");
if (i > -1)
end = i;
while (end > 0 && (output.charAt(end - 1) == ' ' || output.charAt(end - 1) == '-')) {
end--;
}
String formatted = output.substring(0, end);
return formatted;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment