Преобразование нормализованного номера телефона в удобную версию
-
06-07-2019 - |
Вопрос
В моем приложении на C# я использую регулярное выражение для проверки базового формата телефонного номера в США, чтобы убедиться, что пользователь не просто вводит поддельные данные.Затем я удаляю все, кроме цифр, вот так:
(123) 456-7890 x1234
становится
12345678901234
в базе данных.Однако в различных частях моего приложения я хотел бы преобразовать этот нормализованный номер телефона обратно в
(123) 456-7890 x1234
Как лучше всего это сделать?(Кстати, не беспокойтесь об учете международных форматов телефонных номеров.)
Решение
String.Format("{0:(###) ###-#### x ###}", double.Parse("1234567890123"))
Результат: (123) 456-7890 x 123.
Другие советы
Используя регулярное выражение, вы можете заменить:
(\d{3})(\d{3})(\d{4})(\d{4})
с:
(\1) \2-\3 x\4
(Хотя я не знаком с телефонными номерами в США, так что, возможно, это еще не все.)
Я бы просто использовал строку пользовательского формата, чтобы преобразовать число обратно в строку:
class Program
{
static void Main(string[] args)
{
long phoneNumber = 12345678901234;
string phoneNumberString = String.Format("{0:(000) 000-0000 x0000}", phoneNumber);
Console.WriteLine(phoneNumberString);
}
}
Конечно, вы бы выделили это в функцию, которая будет принимать номер телефона как длинный, а затем возвращать строку (с форматом, загруженным или сохраненным как константа в методе, или что-то подходящее для вашей ситуации).
Да, и если у вас есть строка, а не длинная, вы можете легко преобразовать строку в длинную, а затем передать ее в функцию форматирования.Конечно, здесь есть соображения по производительности, если вы делаете это неоднократно (поскольку вы повторяете строку для создания длинной строки, а затем преобразуете ее обратно в строку, хотя вы могли бы просто использовать подстроку).
Если вы поддерживаете только номера США, вы можете просто отформатировать цифры так, чтобы скобки и x отображались там, где вы хотите.
Я бы предпочел сохранить всю строку, я бы проанализировал ее с помощью регулярного выражения для проверки, а затем сохранил в нормализованной строке.
Чтобы заставить его принять любую страну, я бы сделал это:
Я бы добавил код IDD ко всем номерам телефонов, а затем скрыл бы его от пользователей из этой страны.
так:(123) 456-7890 x1234 будет сохранен как +1 (123) 456-7890 x1234
(Perl-совместимое) регулярное выражение будет выглядеть примерно так (совершенно непроверено и не будет работать):
(+\d+)?\s+(((\d{,3}))(?\s+([-.0-9]{6,})\s+((x|ext\w*)\d{ ,4})
- Это необязательное количество цифр, которым предшествует +
- За которым следует один или несколько пробелов
- Затем необязательная группа до 3 цифр между круглыми скобками.
- Затем один или несколько пробелов
- Затем группа из 6 и более цифр, тире или точек
- Затем один или несколько пробелов
- Затем необязательный x или слово, начинающееся с ext (ext, Extension...) и группы до 4 цифр.
У меня была бы база данных пользователей, включая код страны и города, а затем я автоматически заполнял бы их, если они отсутствуют, в стране было бы соглашение о группировке цифр по умолчанию для телефонных номеров (3,4 для США).
- Итак, если вы находитесь в зоне 123 в США и вводите 456.7890, он будет проанализирован как +1 (123) 4567890, и вы увидите его только как 456-7890.
- если вы находитесь в Катаре и вводите номер 4444555 extenshn 33, он сохраняется как +974 4444555 x33, вы увидите его как 4444555 x33
Международный код не будет отображаться для пользователей в одной стране, а код города не будет отображаться для пользователей в той же стране и коде города.Полный номер будет отображаться при наведении курсора мыши (метка HTML?)
Вам НУЖНО разбить это на БД?Если нет, не делайте этого.Если вам ДОЛЖЕН, вы можете хранить разные части в разных полях (код региона, префикс, номер подписчика, расширение).
Или извлеките число и начните анализ.Если там всего 10 цифр, значит, расширения нет.Все цифры после 10, вставьте их в строку после «x» или чего-то еще.
Я сделал нечто подобное в приложении на C++. Я написал сохраненные различные механизмы контактов в виде одной строки, но вместо этого я сделал обратное тому, что вы делаете.Я удалил поля из диалогового окна и построил отформатированное число для хранения в виде строки.
Вот метод расширения, который может помочь:
public static string InsertStringAtPositions(this string str, string insertStr, IEnumerable<int> positions)
{
if (str != null && insertStr != null && positions != null)
{
string newString = string.Empty;
int previousPos = 0;
foreach (var pos in positions)
{
if (pos < str.Length)
{
newString += str.Substring(previousPos, pos - previousPos) + insertStr;
previousPos = pos;
}
}
if (positions.Last() < str.Length)
{
return newString + str.Substring(positions.Last(), str.Length - positions.Last());
}
return newString;
}
return str;
}
Использование:
// Will convert "0399998888" to "03 9999 8888"
number.InsertStringAtPositions(" ", new[] {2, 6});