API формата телефонных номеров Java - PullRequest
28 голосов
/ 28 января 2009

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

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

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

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

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

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

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

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

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

Ответы [ 11 ]

40 голосов
/ 28 января 2009

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

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

<ч />

Обновление:

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

22 голосов
/ 26 октября 2010

Вы можете попробовать эту библиотеку форматирования телефонных номеров Java https://github.com/googlei18n/libphonenumber

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

10 голосов
/ 18 июля 2012

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

/**
 * @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;
}

Формат

Я сделал это в соответствии со своими потребностями, и он принимает цифры:

  1. CountryCode-номер
  2. номер

Коды стран:

Они могут иметь: +, либо один, либо два нуля. Затем за ним может следовать -.

Принимает:

  • +456
  • 00456
  • +1234
  • 01234

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

Rejects:

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

номер

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

Принимает:

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

Расширить это?

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

3 голосов
/ 09 января 2015

Не переизобретай колесо; использовать 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, чтобы красиво отформатировать его действительный номер телефона перед сохранением его в БД или что-то еще.

3 голосов
/ 20 февраля 2011

Последние версии 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

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

3 голосов
/ 28 января 2009

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

2 голосов
/ 01 сентября 2011

Для французского числа, которое выглядит как «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));
}
1 голос
/ 28 января 2009

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

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

1 голос
/ 28 января 2009

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

0 голосов
/ 03 сентября 2014

Мои собственные потребности были очень просты. Мне просто нужно было взять 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...