Подтвердить что ты не робот

API формата номера телефона Java

У меня есть база данных с миллионами телефонных номеров со свободным для всех форматированием. Т.е. пользовательский интерфейс не применяет никаких ограничений и пользователи набирают все, что захотят.

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

Например, номер телефона в системе может выглядеть следующим образом:

(555) 478-1123
555-478-1123    
555.478.1123
5554781123

Учитывая страну США, API будет производить значение "+1 (555) 478-1123" для всех этих. Точный формат не имеет значения, если он согласован.

В системе также есть номера без кодов областей, таких как "478-1123". В этом случае я ожидал бы исключение NoAreaCodeException или что-то подобное.

Также могут быть такие данные, как "abc", которые также должны генерировать исключения.

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

Кто-нибудь видел такой API?

4b9b3361

Ответ 1

Вы можете написать свой собственный (для формата телефона США #):

  • Сбросьте любые нечисловые символы из строки
  • Убедитесь, что оставшаяся строка содержит десять символов
  • Поместите круглые скобки вокруг первых трех символов и тире между шестым и седьмым символами.
  • Подготовьте "+1" к строке

<ч/" >

Обновление:

Недавно Google опубликовал libphonenumber для разбора, форматирования, хранения и проверки международных телефонных номеров.

Ответ 2

Вы можете попробовать эту библиотеку форматирования номера Java http://code.google.com/p/libphonenumber/

Он содержит данные для сотен стран и форматов.

Ответ 3

Простой парсер регулярных выражений

/**
 * @param pPhoneNumber
 * @return true if the phone number is correct
 */
private boolean isPhoneNumberCorrect(String pPhoneNumber) {

    Pattern pattern = Pattern
            .compile("((\\+[1-9]{3,4}|0[1-9]{4}|00[1-9]{3})\\-?)?\\d{8,20}");
    Matcher matcher = pattern.matcher(pPhoneNumber);

    if (matcher.matches()) return true;


    return false;
}

Формат

Я сделал это согласно моим потребностям, и он принимает числа:

  • CountryCode-Number
  • Количество

Коды стран:

Они могут иметь: + или один или два нули. Тогда за ним может следовать a -.

Принимает:

  • +456
  • 00456
  • +1234
  • 01234

Все вышеизложенное может или не может сопровождаться a -

Отклонение:

  • 0456
    • это должно быть:
      • 00456 или +456 или 04444

Число

Простое число с 8-20 цифрами.

Принимает:

  • 00456-12345678
  • +457-12345678
  • +45712345678
  • 0045712345678
  • 99999999

Расширить его?

Не стесняйтесь, поэтому вы можете включить поддержку . или '(' separators. Просто убедитесь, что вы их избегаете, например, для ( используйте \(.

Ответ 4

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

Ответ 5

Последние версии http://code.google.com/p/libphonenumber/ добавили метаданные для многих новых стран и добавили намного больше деталей для некоторых из ранее перечисленных стран.

Текущая версия исходного кода - r74, а файл .jar - в версии 2.6. Предыдущие .jar файлы были скомпилированы для Java 1.6, но с версии libphonenumber версии 2.5.1 они теперь скомпилированы для Java 1.5 и выше.

Не забывайте, что есть также прямой порт кода для JavaScript. Его можно найти в дереве исходного кода в http://code.google.com/p/libphonenumber/source/browse/#svn%2Ftrunk%2Fjavascript

Отчеты об ошибках приветствуются. Активно поощряется обновление метаданных, поскольку даже официальные опубликованные в правительственных списках списки кодов для многих стран являются либо неполными, либо устаревшими.

Ответ 6

Не изобретайте колесо повторно; использовать API, например. http://libphonenumber.googlecode.com/ Этот API дает вам хорошее форматирование. Пример:

String number = "(555) 478-1123";
PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
try {
  Phonenumber.PhoneNumber phoneNumber = phoneNumberUtil.parse(number, Locale.US.getCountry());
} catch (NumberParseException e) {
  // error handling
}

Вы даже можете использовать объект phoneNumber, чтобы красиво отформатировать его действительным номером телефона, прежде чем сохранять его в БД или что-то еще.

Ответ 7

Для французского номера, который выглядит как "01 44 55 66 77", мы можем использовать следующую логику.

DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setGroupingSeparator(' ');  // sometimes '.' is used
DecimalFormat decfmt = new DecimalFormat("0,0", dfs);  // enable grouping
decfmt.setMinimumIntegerDigits(10);  // we always have 10 digits
decfmt.setGroupingSize(2);  // necessary in order to group digits by 2 orders
System.out.println(decfmt.format(144556677));  // outputs "01 44 55 66 77"

Как только это может быть сделано, с API-интерфейсом телефона google, упомянутым выше, мы можем легко проанализировать эти последовательности и переформатировать их в другие формы, такие как "+33 1 44 55 66 77", как показано ниже:

Iterable<PhoneNumberMatch> numbers = PhoneNumberUtil.getInstance().findNumbers(textWithPhoneNums, "FR");
for(Iterator<PhoneNumberMatch> iterator = numbers.iterator(); iterator.hasNext(); ){
    PhoneNumberMatch pnm = iterator.next();
    PhoneNumber number = pnm.number();
    System.out.println(PhoneNumberUtil.getInstance().formatOutOfCountryCallingNumber(number, null));
}

Ответ 8

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

Ответ 9

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

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

Ответ 10

Лучшее, что я нашел, было javax.telephony, которое можно найти здесь: http://java.sun.com/products/javaphone/

У него класс адресов, но, к сожалению, этот класс не решил вашу проблему:( Ну, может быть, вы сможете найти решение, углубляясь в него.

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

Ответ 11

Мои собственные потребности были очень простыми. Мне просто нужно было сделать 7 или 10-значный номер и поместить разделители (тире, период, несколько строк символов и т.д.) Между кодом города, обменом и номером обмена. Любое значение, переданное в метод, который не является числом или не является длиной 7 или 10, просто возвращается. Нулевое значение возвращает пустую строку, а нулевое значение для разделителя рассматривается как пустая строка. Мой код:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
// ...
private String formatPhoneNumber(String phnumber, String separator) {
  phnumber = (phnumber == null) ? "" : phnumber;
  if ((phnumber.length() != 7) && (phnumber.length() != 10)) { return phnumber; }

  // If we get here, 'phnumber' is for sure either 7 or 10 chars long

  separator = (separator == null) ? "" : separator;
  Pattern p = Pattern.compile("([0-9]*)");
  Matcher m = p.matcher(phnumber);
  if (m.matches()) {
   if (phnumber.length() == 7) {
     return phnumber.substring(0, 3) + separator + phnumber.substring(4);
    } else {
     return phnumber.substring(0, 3) + separator + phnumber.substring(3, 6)  
            + separator + phnumber.substring(6);
    }
  // If we get here, it means 1 or more of the chars in 'phnumber'
  // is not a digit and so 'phnumber' is returned just as passed in.
  return phnumber;
}