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

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

(123) 456-7890 x1234

становится

12345678901234

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

(123) 456-7890 x1234

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

У вас есть код для преобразования этого: (123) 456-7890 x1234 в это: 12345678901234?

jrutter 16.09.2009 17:12
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
1
4 115
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

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

с участием:

(\1) \2-\3 x\4

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

Вы ДОЛЖНЫ разбить это на БД? Если нет, не надо. Если вы ДОЛЖНЫ, вы можете хранить разные части в разных полях (Areacode, Prefix, SubscriberNum, Extenion).

Или извлеките число и начните анализ. Если это всего лишь 10 цифр, значит, расширения нет. Все цифры после 10, вставьте их в строку после «x» или чего-то в этом роде.

Я сделал что-то подобное в приложении C++. Я написал сохраненные различные механизмы контактов в виде одной строки, но вместо этого я сделал обратное тому, что вы делаете. Я удалил поля из диалогового окна и построил форматированное число для хранения в виде строки.

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

David Brown 09.01.2009 00:00

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

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

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

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

Мне нравится этот метод (поскольку он дает моим пользователям возможность изменять маску, если им нужно). Однако не удастся ли это сделать, если у входной строки нет расширения?

David Brown 09.01.2009 00:06
Ответ принят как подходящий
String.Format("{0:(###) ###-#### x ###}", double.Parse("1234567890123"))

Результатом будет (123) 456-7890 x 123

это безопасно использовать двойной? В этом случае я бы использовал десятичную дробь.

FryGuy 08.01.2009 23:57

Double имеет достаточно цифр для этой цели, и, поскольку нет дробной части, которая могла бы вызвать ошибки округления, она, вероятно, «сработает». Тем не менее, это не «кажется» правильным, и в целом я бы избегал такого «хитрого» кода.

oefe 09.01.2009 00:10

Этот код не будет работать с 0 в начале строки: 03 9999 9999. Таким образом, это не международное решение, поскольку в Австралии у нас есть коды штатов, которые начинаются с 0.

Jonathan Parker 26.03.2009 03:07

Если вы поддерживаете только номера США, вы можете просто отформатировать цифры, чтобы отображать круглые скобки и 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 extensionshn 33, он сохраняется как +974 4444555 x33, вы увидите его как 4444555 x33

Международный код не будет отображаться для пользователей в той же стране, и код города не будет отображаться для пользователей в той же стране и код города. Полный номер будет отображаться при наведении мыши (метка 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});

Другие вопросы по теме