Преобразование нормализованного номера телефона в удобную для пользователя версию

в моем приложении c# я использую регулярное выражение для проверки базового формата телефонного номера США, чтобы убедиться, что пользователь не просто вводит фиктивные данные. Затем я вычеркиваю все, кроме чисел, так что:

(123) 456-7890 x1234

становится

12345678901234

в базе данных. Однако в различных частях моего приложения я хотел бы преобразовать этот нормализованный номер телефона обратно к

(123) 456-7890 x1234

Как лучше всего это сделать? (Кстати, не беспокойтесь об учете международных форматов номеров телефонов.)

6 ответов


String.Format("{0:(###) ###-#### x ###}", double.Parse("1234567890123"))

приведет к (123) 456-7890 x 123


используя регулярное выражение, Вы можете заменить:

(\d{3})(\d{3})(\d{4})(\d{4})

С:

() - x

(хотя я не знаком с телефонными номерами США, поэтому, возможно, это еще не все.)


Я бы просто использовал строку пользовательского формата, чтобы преобразовать число обратно в строку:

class Program
{
    static void Main(string[] args)
    {
        long phoneNumber = 12345678901234;
        string phoneNumberString = String.Format("{0:(000) 000-0000 x0000}", phoneNumber);
        Console.WriteLine(phoneNumberString);
    }
}

конечно, вы бы разложили его на функцию, которая взяла бы номер телефона как длинный, а затем вернула строку (с форматом, загруженным или сохраненным как константа в методе, или что-то подходящее для вашей ситуации).

О, и если у вас есть строка, а не длинная, вы можете легко преобразовать строку в длинную, а затем передать ее в формат функция. Конечно, здесь есть соображения производительности, если вы делаете это неоднократно (поскольку вы повторяете строку для создания long, а затем преобразуете ее обратно в строку, когда вы можете просто использовать подстроку).


Если вы поддерживаете только номера США, вы можете просто отформатировать цифры, чтобы показать скобки и x, где вы хотите.

Я бы предпочел сохранить всю строку, я бы проанализировал ее с помощью регулярного выражения для ее проверки, а затем сохранить ее в нормализованной строке.

чтобы заставить его принять любую страну, я бы сделал так:

Я бы добавил код IDD ко всем номерам телефонов, а затем скрыть его от пользователей из этой страны.

Так: (123) 456-7890 x1234 будет сохранен как +1 (123) 456-7890 x1234

регулярное выражение (perl-совместимое) будет чем-то вроде (полностью непроверенное и не будет работать):

(+\d+)?\s+(((\d {, 3})) (?\с.-[(+0-9]{6,})\s+((x|ext\w*)\d{,4})

  • это необязательное количество цифр, которым предшествует +
  • с последующим одним или несколькими пробелами
  • затем необязательная группа до 3 цифр между скобками
  • затем одно или несколько пробелов
  • затем a группа из 6 или более цифр, тире или точек
  • затем одно или несколько пробелов
  • затем необязательный x или слово, начинающееся с ext (ext, extension ...) и группа до 4 цифр

У меня была бы база данных пользователей, включая код страны и региона, а затем заполнить их автоматически в случае, если они отсутствуют, страна будет иметь это по умолчанию соглашение о группировке цифр для телефонных номеров (3,4 для США).

  • Итак, если вы в область 123 в США и введите 456.7890, она будет проанализирована как +1 (123) 4567890, и вы увидите ее только как 456-7890
  • если вы находитесь в Катаре и введите номер 4444555 extenshn 33, он хранится как +974 4444555 x33, вы увидите его как 4444555 x33

международный код не будет отображаться для пользователей в той же стране, и код области не будет отображаться для пользователей в той же стране и код области. Полный номер будет отображаться onmouseover (HTML-метка?)


вам нужно разбить его на DB? Если нет, не надо. Если необходимо, то вы можете хранить разные части в разных полях (Areacode, Prefix, SubscriberNum, Extenion).

или извлеките число и начните разбор. Если это только 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});