Каков лучший способ для преобразования номеров телефона в международный формат (E.164) с помощью Java?

Вы можете найти ответ, который вы хотите найти в cppreference .

При использовании сразу после ввода с разделителями-пробелами, например. после int n; std::cin >> n;, getline потребляет символ конца, оставленный на входном потоке оператором >>, и немедленно возвращается. Общее решение состоит в том, чтобы игнорировать все оставшиеся символы в строке ввода с cin.ignore(std::numeric_limits::max(), '\n'); перед переключением на линейно-ориентированный вход.

blockquote>

28
задан Vihung 30 October 2008 в 16:11
поделиться

7 ответов

Это было мое решение:

public static String FixPhoneNumber(Context ctx, String rawNumber)
{
    String      fixedNumber = "";

    // get current location iso code
    TelephonyManager    telMgr = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
    String              curLocale = telMgr.getNetworkCountryIso().toUpperCase();

    PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
    Phonenumber.PhoneNumber     phoneNumberProto;

    // gets the international dialling code for our current location
    String              curDCode = String.format("%d", phoneUtil.getCountryCodeForRegion(curLocale));
    String              ourDCode = "";

    if(rawNumber.indexOf("+") == 0)
    {
        int     bIndex = rawNumber.indexOf("(");
        int     hIndex = rawNumber.indexOf("-");
        int     eIndex = rawNumber.indexOf(" ");

        if(bIndex != -1)
        {
            ourDCode = rawNumber.substring(1, bIndex);
        }
        else if(hIndex != -1) 
        {               
            ourDCode = rawNumber.substring(1, hIndex);
        }
        else if(eIndex != -1)
        {
            ourDCode = rawNumber.substring(1, eIndex);
        }
        else
        {
            ourDCode = curDCode;
        }           
    }
    else
    {
        ourDCode = curDCode;
    }

    try 
    {
      phoneNumberProto = phoneUtil.parse(rawNumber, curLocale);
    } 

    catch (NumberParseException e) 
    {
      return rawNumber;
    }

    if(curDCode.compareTo(ourDCode) == 0)
        fixedNumber = phoneUtil.format(phoneNumberProto, PhoneNumberFormat.NATIONAL);
    else
        fixedNumber = phoneUtil.format(phoneNumberProto, PhoneNumberFormat.INTERNATIONAL);

    return fixedNumber.replace(" ", "");
}

Я надеюсь, что это поможет кому-то с той же проблемой.

Наслаждайтесь и пользуйтесь свободно.

3
ответ дан Matt Fenwick 14 October 2019 в 10:25
поделиться

Это очень сложная задача, так как телефонные номера пишутся по-разному почти в каждой стране.

Раньше мы вели список REGEXP (мы поддерживали 19 форматов) для анализа 3 частей числа, а затем преобразовывали эти 3 части в «+ {1} {2} {3}».

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

0
ответ дан Vilmantas Baranauskas 14 October 2019 в 10:25
поделиться

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

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

  1. Полоса, весь пробел от номера

  2. Переводит всю альфу в цифры - использование таблицы поиска буквы к цифре (например,-> 2, B-> 2, C-> 2, D-> 3) и т.д. для клавиатуры (я не знал, что некоторые клавиатуры распределяют их по-другому)

  3. Полоса вся пунктуация - хранение предыдущего '+' неповрежденный, если это существует (в случае, если число уже находится в своего рода международном формате).

  4. Определяют, имеет ли число международный префикс набора номера для контекста страны - например, если бы исходным контекстом является Великобритания, я видел бы, запускается ли это с '00' - и замените его '+ '. Я в настоящее время не проверяю, сопровождаются ли цифры после эти '00' международным кодом набора для целевой страны. Я ищу международный префикс набора номера для исходной страны в таблице поиска (например, ГБ-> '00', США-> '011' и т.д.)

  5. Определяют, имеет ли число локальный префикс набора номера для контекста страны - например, если бы исходным контекстом является Великобритания, я надеялся бы видеть, запускается ли это с '0' - и замените его '+' сопровождаемый международным кодом набора для целевой страны. Я ищу локальный префикс набора номера для исходной страны в таблице поиска (например, ГБ-> '0', США-> '1' и т.д.), и международный код набора для целевой страны в другой таблице поиска (например.'GB' = '44', США = '1')

, Это, кажется, работает на все, что я бросил в него до сих пор - за исключением +44 (0) 1234-567-890 ситуаций - я добавлю проверку особого случая на ту.

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

телефонные компании, кажется, имеют дело с этой вещью каждый день. Я никогда не получаю непоследовательные результаты когда набираемые номера с помощью PSTN. Например, в США (где мобильные телефоны имеют те же коды зоны как наземные линии, я мог набрать +1-123-456-7890, или 011-1-123-456-7890 (то, где 011 международный префикс набора номера в США и 1, является международным кодом набора для США), 1-123-456-7890 (где 1 локальный префикс набора номера в США) или даже 456-7890 (предположение, что я был в 123 кодах зоны в то время), и получите те же результаты каждый раз. Я предполагаю, что внутренне эти набранные номера преобразовываются в тот же стандартный формат E.164, и что преобразование все сделано в программном обеспечении.

1
ответ дан Vihung 14 October 2019 в 10:25
поделиться

Я не знаю о стандартной библиотеке или платформе, доступной для форматирования номеров телефона в E.164.

решение использовало для нашего продукта, который требует, чтобы PBX форматирования, обеспеченный идентификатор вызывающего абонента в E.164, развернул файл (таблица базы данных), содержащая данные о формате E.164 для всех применимых стран. Это имеет преимущество, что приложение может быть обновлено (для обработки всех странных угловых случаев в различных телефонных сетях) w/out требующие изменения в производственной кодовой базе.

таблица содержит строку для каждого кода страны и информации относительно длины кода зоны и длины подписчика. Могут быть многократные въезды для страны в зависимости от того, какие изменения возможны с длинами кода зоны и номера абонента.

Используя Новозеландский PSTN (частичный) план набора как пример таблицы..

CC  AREA_CODE  AREA_CODE_LENGTH  SUBSCRIBER  SUBSCRIBER_LENGTH
64                            1              7
64         21                 2              7
64        275                 3              6

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

0
ответ дан Henk 14 October 2019 в 10:25
поделиться

В некоторых странах можно проверить 112 как действительный телефонный номер, но если Вы засунете код страны перед ним, то это больше не будет допустимо. В других странах Вы не можете проверить 112, но можно проверить 911 как действительный телефонный номер.

я видел некоторые телефоны, которые помещают Q на 7 ключей и Z на 9 ключах. Я видел некоторые телефоны, которые помещают Q и Z на 0 ключах, и некоторых, которые помещают Q и Z на 1 ключе.

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

В половине Северной Америки (код страны 1), второе правило цифры раньше было 0 или 1 для кодов зоны, но то правило ушло 10 лет назад.

0
ответ дан Windows programmer 14 October 2019 в 10:25
поделиться

Говоря на основе опыта при записи такого рода вещи, действительно трудно сделать с 100%-й надежностью. Я записал некоторый код Java, чтобы сделать это, которое довольно хорошо в обработке данных, которые мы имеем, но не будем применимы в каждой стране. Вопросы, которые необходимо задать:

символ должны пронумеровать отображения, последовательные между странами? США используют многое из этого (например, 1800-GOT-MILK), но в Австралии, как один пример, его довольно редкое. То, что необходимо было бы сделать, гарантируют, что Вы делали корректное отображение для рассматриваемой страны, если это варьируется (это не могло бы). Я не знаю то, что делают страны, которые используют различные алфавиты (например, Cyrilic в России и бывших странах стран Восточного блока);

необходимо признать, что решением не составят 100%, и Вы не должны ожидать, что он будет. Необходимо проявить "лучшее предположение" подход. Например, нет никакого реального способа знать, что 132345 действительный телефонный номер в Австралии, как 1300 123 456, но что это только два шаблона, которые являются для 13xx числа, и они не являются вызываемыми из-за границы;

также необходимо спросить, хотите ли Вы проверить регионы (коды зоны). Я полагаю, что США используют систему, где вторая цифра кода зоны является 1 или 0. Это, возможно, когда-то имело место, но я не уверен, применяется ли это все еще. Безотносительно случая много других стран будут иметь другие правила. В Австралии допустимых кодах зоны для наземных линий и мобильный (ячейка) телефоны являются двумя цифрами (первое 0). 08, 03 и 04 все допустимы. 01 не. Как Вы обслуживаете это? Вы хотите?

Страны используют различные соглашения, неважно, сколько цифр они пишут. Необходимо решить, хотите ли Вы принять что-то другое, чем "норма". Они все распространены в Австралии:

  • (02) 1234 5678
  • 02 1234 5678
  • 0411 123 123 (но я никогда не видел 04 1112 3456)
  • 131 123
  • 13 1123
  • 131 123
  • 1 300 123 123
  • 1300 123 123
  • 02-1234-5678
  • 1300-234-234
  • +44 78 1234 1234
  • +44 (0) 78 1234 1234
  • +44-78-1234-1234
  • +44-(0) 78-1234-1234
  • 0011 44 78 1234 1234 (0011 стандартный международный код набора)
  • (44) 078 1234 1234 (не распространенный)

И это просто первое, что пришло на ум. Для одной страны. Во Франции, например, его общее запись номер телефона в парах числа (12 34 56 78) и они объявляют его что слишком: вместо:

ООН (один), deux (два), trois (три)...

погружают (двенадцать), trente-quatre (тридцать четыре)...

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

Также некоторые люди могут добавить добавочные номера по номерам телефона, возможно с "расширением" или подобным сокращением. Вы хотите обслужить это?

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

10
ответ дан toolkit 14 October 2019 в 10:25
поделиться

Честно говоря, это кажется, что у Вас уже есть большинство оснований, охваченных.

+44 (0) 800 форматов, иногда (неправильно) используемых в Великобритании, являются раздражающими и не являются строго допустимыми согласно E.123, который является рекомендацией ITU-T для того, как должны быть отображены числа. Если у Вас нет копии E.123, он достойный внимания.

Если это имеет значение, сама телефонная сеть не всегда использует E.164. Часто будет флаг в ISDN передача сигналов сгенерированном PBX (или в сети, если Вы будете по паровому телефону), который говорит сеть, является ли набираемое число локальным, национальным или международным.

1
ответ дан Alnitak 14 October 2019 в 10:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: