В моем приложении на C# я использую регулярное выражение для проверки основного формата телефонного номера в США, чтобы убедиться, что пользователь не просто вводит поддельные данные. Затем я вычеркиваю все, кроме чисел, так что это:
(123) 456-7890 x1234
становится
12345678901234
в базе данных. Однако в различных частях моего приложения я хотел бы преобразовать этот нормализованный номер телефона обратно в
(123) 456-7890 x1234
Как лучше всего это сделать? (Кстати, не беспокойтесь об учете форматов международных телефонных номеров.)





Используя регулярное выражение, вы можете заменить:
(\d{3})(\d{3})(\d{4})(\d{4})
с участием:
(\1) \2-\3 x\4
(Хотя я не знаком с телефонными номерами в США, так что, возможно, это еще не все.)
Вы ДОЛЖНЫ разбить это на БД? Если нет, не надо. Если вы ДОЛЖНЫ, вы можете хранить разные части в разных полях (Areacode, Prefix, SubscriberNum, Extenion).
Или извлеките число и начните анализ. Если это всего лишь 10 цифр, значит, расширения нет. Все цифры после 10, вставьте их в строку после «x» или чего-то в этом роде.
Я сделал что-то подобное в приложении C++. Я написал сохраненные различные механизмы контактов в виде одной строки, но вместо этого я сделал обратное тому, что вы делаете. Я удалил поля из диалогового окна и построил форматированное число для хранения в виде строки.
К сожалению, да. Приложение представляет собой интерфейс к существующей базе данных, в которой есть правила форматирования телефонных номеров. Поверьте, если бы я мог избежать всей этой ерунды, я бы так и поступил. :П
Я бы просто использовал строку настраиваемого формата, чтобы преобразовать число обратно в строку:
class Program
{
static void Main(string[] args)
{
long phoneNumber = 12345678901234;
string phoneNumberString = String.Format("{0:(000) 000-0000 x0000}", phoneNumber);
Console.WriteLine(phoneNumberString);
}
}
Конечно, вы бы разложили его на функцию, которая будет принимать номер телефона как длинный, а затем возвращать строку (с загруженным или сохраненным форматом как константа в методе или что-то подходящее для вашей ситуации).
Да, и если у вас это строка, а не длинная, вы можете легко преобразовать строку в длинную, а затем передать ее в функцию форматирования. Конечно, здесь есть соображения производительности, если вы делаете это неоднократно (поскольку вы повторяете строку для создания длинного, а затем конвертируете его обратно в строку, когда вы можете просто использовать подстроку).
Мне нравится этот метод (поскольку он дает моим пользователям возможность изменять маску, если им нужно). Однако не удастся ли это сделать, если у входной строки нет расширения?
String.Format("{0:(###) ###-#### x ###}", double.Parse("1234567890123"))
Результатом будет (123) 456-7890 x 123
это безопасно использовать двойной? В этом случае я бы использовал десятичную дробь.
Double имеет достаточно цифр для этой цели, и, поскольку нет дробной части, которая могла бы вызвать ошибки округления, она, вероятно, «сработает». Тем не менее, это не «кажется» правильным, и в целом я бы избегал такого «хитрого» кода.
Этот код не будет работать с 0 в начале строки: 03 9999 9999. Таким образом, это не международное решение, поскольку в Австралии у нас есть коды штатов, которые начинаются с 0.
Если вы поддерживаете только номера США, вы можете просто отформатировать цифры, чтобы отображать круглые скобки и 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,4 для США).
Международный код не будет отображаться для пользователей в той же стране, и код города не будет отображаться для пользователей в той же стране и код города. Полный номер будет отображаться при наведении мыши (метка HTML?)
Вот способ расширения, который может помочь:
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});
У вас есть код для преобразования этого: (123) 456-7890 x1234 в это: 12345678901234?