Last active
December 12, 2015 06:28
-
-
Save dgmltn/4729109 to your computer and use it in GitHub Desktop.
iPhone Dialpad-like dynamic phone number formatter.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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