Комментарии 98
У меня таким макаром:
Буквы на цифры не подменяю, кроме как для США и нескольких стран такого и не нужно.
// function phone($number, $format = '[1] [(3)] 3-2-2'){ echo phone('+7 812 123 45 67'); // +7 (812) 123-45-67 echo phone('8 812 123 45 67'); // 8 (812) 123-45-67 echo phone('8121234567'); // (812) 123-45-67 echo phone('1234567'); // 123-45-67 $format = '[([1 ]4)] 2-2-2'; echo phone('+78121234567', $format); // (+7 8121) 23-45-67 echo phone('88121234567', $format); // (8 8121) 23-45-67 echo phone('8121 23 45 67', $format); // (8121) 23-45-67 echo phone('234567', $format); // 23-45-67
Буквы на цифры не подменяю, кроме как для США и нескольких стран такого и не нужно.
-1
Замечательная функция, буду использовать.
А как быть с номерами, в которых указывается добавочный номер?
Например, +7 123 456-7899 доб. 777
А как быть с номерами, в которых указывается добавочный номер?
Например, +7 123 456-7899 доб. 777
0
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Да я б с удовольствием, но при этом, если я правильно понял, нужно вбивать в массив данных все города мира, а у меня достаточно проверить исключения, а потом просто «вырезать» фиксированное количество знаков, если среди исключений совпадений нет.
0
Имеет смысл сделать дерево с несколькими вершинами, чтобы использовать его не только по прямому назначению, но и для форматирования номеров, где код города присутствует, а страна — нет.
0
А ещё есть (были точно) приколы, что у города два кода одновременно, например 4152 и 41522 — использовалось (а может и используется до сих пор) при переходе с 5-ти значной городской нумерации на 6-ти значную, то есть часть городских номеров 5-ти значная, а часть 6-ти
0
Ну вы же понимаете что разница только в записи? Тоесть во втором случае код тоже 4152, просто все номера начинаются с двойки.
0
Судя по данным с www.hella.ru/code/codeuro.htm, это именно код пятизначный, т.е. в одном случае (4152), а в другом — (41522). А вот с т.з. маршрутизации на АТС-ках, Вы правы, им достаточно тупо проверить пятую цифру кода и направить ее либо в область, либо в город.
0
Для междугородней записи разницы нет, а вот для жителей города, афаик, есть разница, как-то там одновременно сосуществуют (если не закончился этот бардак) 5-ти и 6-ти значные номера (кажется цифровые АТС перевели на 6-ти значные, а «декадно-шаговые» оставили на 5-ти значных). Увидев запись где-нить в профиле на форуме 8(4152)25-55-55 :) многие будут набирать 25-55-55, хотя надо 5-55-55 (может цифровая АТС и соединит по 25-55-55 с 5-55-55, но это будет фича, а аналоговая, афаик, не соединит, поскольку не сообразит, что первую цифру ей надо игнорить)
0
В Харькове тоже самое сейчас — 057 и 0572
0
Внутри города Стаханова телефоны из 5-ти знаков 4-11-11. Зачастую его так и дают в городских СМИ.
-1
А как кто хранит телефонный номера в базе? В том формате как ввел пользователь или приводите к какому-то стандарту?
Если в формате «как ввел пользователь» встает проблема поиска одинаковых номеров по базе. Один пользователь ввел +7915 другой 8915 итп
Если в формате «как ввел пользователь» встает проблема поиска одинаковых номеров по базе. Один пользователь ввел +7915 другой 8915 итп
0
Очень круто код подсветили, пользовались чем-то или, не дай бог, вручную?
А результат, вам неплохо было бы оформить в виде pear-модуля например
А результат, вам неплохо было бы оформить в виде pear-модуля например
+1
Только у нас принято в 7-значных номерах разделять последние четыре цифры по две, т.е. 654-12-43.
А то что вы написали, это английский стандарт — у них вообще принято произносить большие числа группами (например год), у нас такого нет.
Вообще один известный дизайнер все правильно по этому поводу написал.
А то что вы написали, это английский стандарт — у них вообще принято произносить большие числа группами (например год), у нас такого нет.
Вообще один известный дизайнер все правильно по этому поводу написал.
0
Итак, я поставил вам минус. Давайте разберемся, за что именно. Для начала, вы не учитываете того, что в разных странах используются разные разделители групп:
Сравните 640.453.4513 и 07787 525 123.
Дальше. Сравните номер в Лондоне и Эдинбурге:
(020) 7567 8452 и (0131) 123 2153.
Дефисов пока не видно. Ни одного. А вот вам телефонный номер в Париже:
01 22 14 34 98 — странно выглядит, правда? А если записать его в международном формате, то еще страннее: +33 1 2214 3498.
Короче говоря, пилить и пилить. Делать локальные решения в стиле «А у нас нет клиентов за МКАДом» уже давно не модно, решение этой задачи существуют и я предлагаю вам воспользоваться поисковиком для этого и найти хорошо работающее, проверенное решение данной задачи. Или же решайте задачу целиком, вместе со всеми исключениями и edge case'ами.
Сравните 640.453.4513 и 07787 525 123.
Дальше. Сравните номер в Лондоне и Эдинбурге:
(020) 7567 8452 и (0131) 123 2153.
Дефисов пока не видно. Ни одного. А вот вам телефонный номер в Париже:
01 22 14 34 98 — странно выглядит, правда? А если записать его в международном формате, то еще страннее: +33 1 2214 3498.
Короче говоря, пилить и пилить. Делать локальные решения в стиле «А у нас нет клиентов за МКАДом» уже давно не модно, решение этой задачи существуют и я предлагаю вам воспользоваться поисковиком для этого и найти хорошо работающее, проверенное решение данной задачи. Или же решайте задачу целиком, вместе со всеми исключениями и edge case'ами.
+4
Справедливости ради, библиотека на которую я указал, тоже отнюдь не совершенна.
0
Окей, согласен.
Добавлю паттерн форматирования к информации о стране в базу и обновлю код.
Спасибо.
Добавлю паттерн форматирования к информации о стране в базу и обновлю код.
Спасибо.
0
Тут вообще-то все еще хуже. Во-первых, если ты не знаешь страну, для которой делаешь форматирование, задача уже нерешаемая в принципе. Во-вторых, в зависимости от конкретного города (Самара vs Нижневартовск) форматирование номера будет отличаеться т.к. разной длины нумерация, но ты это учитываешь. Теперь надо убиться и выяснить информацию по нумерации для всех городов мира. Это сложно, но возможно — но здесь уже придется банально искать баланс между универсальностью и сложностью.
+1
Это задача из Data Quality.
Простым деревом не решить.
тут нужен аналог КЛАДР.
Ведь как ни крути а телефонный номер — это тот же адрес, только электронный. В нем зашита и страна, и город, и даже район города, а при нужных базах дом и квартира. =)
А так как адреса никогда в дерево утрамбовать не получиться, то и решение идеальным не будет.
То что у вас сделано, достойно, но не покрывает всего поля вариантов.
Есть специальные сервисы которые зарабатывают на такой чистке данных.
Поверьте на слово, они не будут продавать услуги основанные на простом коде, так как задача требует сложных алгоритмов.
В российском сегменте такими задачами занимаются iqsystems.ru и hflabs.ru
Есть еще, но эти компании наиболее продвинулись по данному направлению.
Простым деревом не решить.
тут нужен аналог КЛАДР.
Ведь как ни крути а телефонный номер — это тот же адрес, только электронный. В нем зашита и страна, и город, и даже район города, а при нужных базах дом и квартира. =)
А так как адреса никогда в дерево утрамбовать не получиться, то и решение идеальным не будет.
То что у вас сделано, достойно, но не покрывает всего поля вариантов.
Есть специальные сервисы которые зарабатывают на такой чистке данных.
Поверьте на слово, они не будут продавать услуги основанные на простом коде, так как задача требует сложных алгоритмов.
В российском сегменте такими задачами занимаются iqsystems.ru и hflabs.ru
Есть еще, но эти компании наиболее продвинулись по данному направлению.
0
substr($phone, 0,1)=='1'Что это? $phone[0] == '1'
0
$phone = preg_replace("/[^0-9A-Za-z]/", "", $phone);Ваша функция не понимает UTF-8? Какую кодировку она вообще-то требует?
0
UTF? В телефонном номере? Вы в ту ветку пишете? :)
Или я отстал от жизни и телефонные номера теперь указывают в UTF?
Или я отстал от жизни и телефонные номера теперь указывают в UTF?
+1
Процитированный мною код удаляет из строки все не цифры и не латинские буквы. Из чего я делаю вывод, что вы там ожидаете любые символы. В какой кодировке вы ожидаете эти символы?
Кроме того, взгляните на клавиатуру любого русифицированного офисного телефона. Там есть русские буквы. Не только американцы подбирают буквенные аналоги к номерам своих телефонов, в России это не прижилось, но в европах встречается, а там (сюрприз!) не всегда только латинские буквы. А их надо как-то кодировать.
Кроме того, взгляните на клавиатуру любого русифицированного офисного телефона. Там есть русские буквы. Не только американцы подбирают буквенные аналоги к номерам своих телефонов, в России это не прижилось, но в европах встречается, а там (сюрприз!) не всегда только латинские буквы. А их надо как-то кодировать.
+1
> +7(926)387-48-14
Брать цифры сотового номера в скобки неграмотно. В скобки берут те цифры, которые при определённых условиях можно не набирать. В случае с сотовым номером таких условий не существует. Открывающую скобку от предыдущей цифры и закрывающую от последующей следует отбивать пробелом.
Брать цифры сотового номера в скобки неграмотно. В скобки берут те цифры, которые при определённых условиях можно не набирать. В случае с сотовым номером таких условий не существует. Открывающую скобку от предыдущей цифры и закрывающую от последующей следует отбивать пробелом.
+5
Добавляю в список планируемых фиксов, спасибо.
+1
Пардоньте, промахнулся и поставил минус, исправился кармически
Добавлю, что по этому же обоснованию в случае городских номеров в скобки заключается и код старны и код города, разделяемые пробелом.
Добавлю, что по этому же обоснованию в случае городских номеров в скобки заключается и код старны и код города, разделяемые пробелом.
+1
Да, имеет смысл добавить параметр для возможности определения локальных номеров, если дана информация, относительно какого города выводить.
+1
Геотаргетинг =)
У Лебедева немало про телефонные номера писали. Например, вот:
www.artlebedev.ru/tools/technogrette/xslt/phone-numbers/
www.artlebedev.ru/kovodstvo/sections/91/
У Лебедева немало про телефонные номера писали. Например, вот:
www.artlebedev.ru/tools/technogrette/xslt/phone-numbers/
www.artlebedev.ru/kovodstvo/sections/91/
+1
Вот кстати молодая рубёвая библиотека для тех же целей: github.com/elskwid/phone
Вот отсюда rubygems.org/gems/elskwid-phone/ можно забрать gem и потестить, как работает либа через irb.
Вот отсюда rubygems.org/gems/elskwid-phone/ можно забрать gem и потестить, как работает либа через irb.
0
+44(0870)770-53-70
вот этот номер неправильный. Должно быть +44 (0) 870-770-53-70.
0 в скобках, потому что внутри страны набирается начиная с 0. А +44 — то, что его заменяет при звонках извне.
870 — код города (ну или области)
вот этот номер неправильный. Должно быть +44 (0) 870-770-53-70.
0 в скобках, потому что внутри страны набирается начиная с 0. А +44 — то, что его заменяет при звонках извне.
870 — код города (ну или области)
+1
Обсуждалось выше уже, но не могли бы Вы уточнить, код города всегда указывается вне скобок в этом случае?
Т.е. если я живу в городе 870, я все равно должен набирать 870-…, а если в другом, то 0-870-…?
Т.е. если я живу в городе 870, я все равно должен набирать 870-…, а если в другом, то 0-870-…?
0
То есть российские номера в это стандарте должны выглядеть так: +7 (8) 123-456-78-90?
0
Нет, не так. +7 и (8) вместе — это уже ошибкой пахнет :)
Из обсуждений выше видно, что в скобках указывается то, что набирать необязательно.
Другими словами, для москвичей (если бы остался 095, а не два кода, будь они неладны), указывалось бы 123-45-67 при локальном номере, 8 812 123-45-67, при междугороднем, а т.к. мы часто не знаем, откуда читатель номера, то пишем 8 (812) 123-45-67, намекая на то, что 812 набирать надо только в случае, если номер нелокален.
Напротив дело обстоит с мобильными операторами. Получается, что писать 8(926)123-45-67 в корне неправильно, т.к. без 926 номер набирать нельзя.
Я обязательно покопаюсь подробно в этой теме и выкачу новый топик вместе с реализованными находками в обновленном коде функции, преобразовав ее в полноценный класс.
Из обсуждений выше видно, что в скобках указывается то, что набирать необязательно.
Другими словами, для москвичей (если бы остался 095, а не два кода, будь они неладны), указывалось бы 123-45-67 при локальном номере, 8 812 123-45-67, при междугороднем, а т.к. мы часто не знаем, откуда читатель номера, то пишем 8 (812) 123-45-67, намекая на то, что 812 набирать надо только в случае, если номер нелокален.
Напротив дело обстоит с мобильными операторами. Получается, что писать 8(926)123-45-67 в корне неправильно, т.к. без 926 номер набирать нельзя.
Я обязательно покопаюсь подробно в этой теме и выкачу новый топик вместе с реализованными находками в обновленном коде функции, преобразовав ее в полноценный класс.
0
>8 812 123-45-67, при междугороднем, а т.к. мы часто не знаем, откуда читатель номера, то пишем 8 (812) 123-45-67, намекая на то, что 812 набирать надо только в случае, если номер нелокален.
Но если номер локален, то и 8 не надо набирать, а извне страны надо набирать +7.
В общем по хорошему надо отслеживать посетителя, для местных писать 123-45-67, для той же страны (8 812) 123-45-67 или (812) 123-45-67 — про 8 сам догадается :), для других стран (+7 812) 123-45-67.
Хотя, если это на сайте рассчитанном на российскую аудиторию, то, наверное, вполне достаточно (812) 123-45-67. Иностранец, по идее, должен сообразить и узнать код России (тем более что ему возможно не +7 надо будет вводить, а какой-нибудь 110 7). Если же не заморачиваться, то в хидере/футере сайта писать (812) 123-45-67, а в «Контактах» несколько вариантов одного и того же номера типа
USA: 110 7 812 123-4567
Europe: 00 7 812 123.45.67
Mobile: +7 812 123-45-67
или везде ограничиться +7 812 123-45-67
Но если номер локален, то и 8 не надо набирать, а извне страны надо набирать +7.
В общем по хорошему надо отслеживать посетителя, для местных писать 123-45-67, для той же страны (8 812) 123-45-67 или (812) 123-45-67 — про 8 сам догадается :), для других стран (+7 812) 123-45-67.
Хотя, если это на сайте рассчитанном на российскую аудиторию, то, наверное, вполне достаточно (812) 123-45-67. Иностранец, по идее, должен сообразить и узнать код России (тем более что ему возможно не +7 надо будет вводить, а какой-нибудь 110 7). Если же не заморачиваться, то в хидере/футере сайта писать (812) 123-45-67, а в «Контактах» несколько вариантов одного и того же номера типа
USA: 110 7 812 123-4567
Europe: 00 7 812 123.45.67
Mobile: +7 812 123-45-67
или везде ограничиться +7 812 123-45-67
+1
На самом деле как раз и будет выглядеть так, как вы написали :) Это же смесь международного и локального набора. В ЮК этот номер набирался бы 0870 770 53 70.
А набирают там по-моему всегда полный номер. Но могу ошибаться.
А набирают там по-моему всегда полный номер. Но могу ошибаться.
0
Тесты в виде echo — это шикарно. Я уж не говорю про PHPUnit, но может быть всё-таки сделать отдельный файл с проверками?
-2
Уважаемый, Вы совсем потеряли восприятие размеров?)) PHPUnit на одной функции? Отдельный файл с проверками? :)
Это демонстрация, а не тесты, если уж совсем быть точным.
Я понимаю, что существуют «паттерны правильного программирования», но не надо бить по мухе и пушки ;-)
Это демонстрация, а не тесты, если уж совсем быть точным.
Я понимаю, что существуют «паттерны правильного программирования», но не надо бить по мухе и пушки ;-)
+1
решали и решили телефоны полгода назад — помогает нам база кодов всех стран и всех городов.
Ито, иногда оказывается что год назад какойнить город перешол с пятизначки на четырех значку или наоборот и надо править.
Кстати — для тех кто в танке — БОЛЬШАЯ часть России использует четырехзначный и более код города.
Ито, иногда оказывается что год назад какойнить город перешол с пятизначки на четырех значку или наоборот и надо править.
Кстати — для тех кто в танке — БОЛЬШАЯ часть России использует четырехзначный и более код города.
0
бОльшая часть РФ использует пятизначный код города.
0
А где решили, можно посмотреть?
0
www.gdeetotdom.ru/personal/realty/new.php
забиваете номер телефона( правый верхний угол)
переводите фокус на другой елемент и жмете ф5( и соглашаетесь уйти со страницы )
после обновления получитите «правилный номер»
правда, если номер системе не понравиться — не получите вообще ничего :)
забиваете номер телефона( правый верхний угол)
переводите фокус на другой елемент и жмете ф5( и соглашаетесь уйти со страницы )
после обновления получитите «правилный номер»
правда, если номер системе не понравиться — не получите вообще ничего :)
0
а как поддерживать код?
перенумерация (дефалтсити тому пример), присоединение населенных пунктов.
да и просто новые коды городов?
перенумерация (дефалтсити тому пример), присоединение населенных пунктов.
да и просто новые коды городов?
0
Если Вы читали внимательно, то должны были заметить, что в отличие от kashey, который использует полную тяжелую базу данных кодов всех стран и всех городов, я использую лишь информацию о том, сколько цифр в коде города для каждой страны является обычным + список исключений.
Таким образом, при появлении нового областного города в РФ, например, моя БД будет продолжать оставаться актуальной, т.к. областной город скорее всего получит пятизначный код, а вот kashey (если он достаточно описал свой метод) придется добавить этот город в свою базу.
Таким образом, при появлении нового областного города в РФ, например, моя БД будет продолжать оставаться актуальной, т.к. областной город скорее всего получит пятизначный код, а вот kashey (если он достаточно описал свой метод) придется добавить этот город в свою базу.
0
не придется.
есть режим «работы по дефолту»
в основном используется для разных там мобилок.
В общем случае исходя из обшего колличества цифер можно предположить сколько из них вероятно будет в коде города
есть режим «работы по дефолту»
в основном используется для разных там мобилок.
В общем случае исходя из обшего колличества цифер можно предположить сколько из них вероятно будет в коде города
0
При коде города в 3 цифры, номер составляет 7.
0
Прошу прощения, нажал CTRL+Enter и не дописал…
При коде города в 4 цифры, номер составляет 6.
При коде в 5 цифр, на номер будет 5.
Во всех случаях полный номер с кодом города остается одинаковой длины, как Вы определяете вероятность?)
При коде города в 4 цифры, номер составляет 6.
При коде в 5 цифр, на номер будет 5.
Во всех случаях полный номер с кодом города остается одинаковой длины, как Вы определяете вероятность?)
0
Эмпирически :)
особенно в этом нам помогают конечные люди которые звонял и жалуются что «в новосибирске построили новую АТС и вот у нас код города на одну циферку меньше стал»
Правда потом звонят и говорят что вообще старый номер тоже правильный, и только полгорода перешло на новую нумерацию…
Это я к тому что на самом деле — не благодарное это дело, и единственный нормальный вариант — работать через БД, которую и пополнять по возможности.
особенно в этом нам помогают конечные люди которые звонял и жалуются что «в новосибирске построили новую АТС и вот у нас код города на одну циферку меньше стал»
Правда потом звонят и говорят что вообще старый номер тоже правильный, и только полгорода перешло на новую нумерацию…
Это я к тому что на самом деле — не благодарное это дело, и единственный нормальный вариант — работать через БД, которую и пополнять по возможности.
0
Понятно, но по сути получается что модель работы в любом случае практически одна и та же: у Вас, насколько я понял, полная БД городов и стран, а у меня более оптимизированная по весу с использованием исключений для тех городов, которые выбиваются из, например, правила «в РФ города имеют 5-значный номер».
Код Вашей базы, естественно, Вы никуда не выкладывали?
Код Вашей базы, естественно, Вы никуда не выкладывали?
0
Посмотрел форму, красиво отрабатывает, правда почему-то спрашивает про сохранение только один раз, при втором обновлении страницы уже ничего не сохраняет.
0
Все же я думаю что без базы знаний (как её реализовывать не принципиально) не обойтись.
Привязка телефонного номера должна быть к определенной территории (точность мы сами выбираем, хотим до населенного пункта — один размер базы, хотим до дома — другой).
Аналогично и с операторами сотовой связи — у них так же есть свои внутренние коды привязанные к территории страны.
Привязка телефонного номера должна быть к определенной территории (точность мы сами выбираем, хотим до населенного пункта — один размер базы, хотим до дома — другой).
Аналогично и с операторами сотовой связи — у них так же есть свои внутренние коды привязанные к территории страны.
+1
Все верно.
В моем решение как раз используется некоторая база данных, позволяющая однозначно определить размер кода города, основываясь на доступных в справочниках данных, в том числе имеется список кодов сотовых операторов.
В моем решение как раз используется некоторая база данных, позволяющая однозначно определить размер кода города, основываясь на доступных в справочниках данных, в том числе имеется список кодов сотовых операторов.
0
А как дела с полнотой, точностью и актуальностью у этой БД?
Основная проблема в DQ именно актуальные справочники.
Основная проблема в DQ именно актуальные справочники.
+1
Источники указаны в конце статьи, для россии был использован www.hella.ru/code/codcity.htm и МТТ.
Собственно, т.к. данная тема получила поддержку и развитие, к поправкам функции добавлю еще пару источников и укажу наиболее актуальные для дальнейшего отслеживания.
Собственно, т.к. данная тема получила поддержку и развитие, к поправкам функции добавлю еще пару источников и укажу наиболее актуальные для дальнейшего отслеживания.
0
попросили опубликовать:
Здравствуйте, Александр!
На хабре не зарегистрирован, поэтому не могу прокомментировать статью Форматирование телефонных номеров на PHP, а контакты автора не нашел. Увидел, что Вы принимаете активное участие в обсуждении, поэтому написал Вам с просьбой опубликовать мой комментарий. Прошу прощения за беспокойство.
В России длина телефонного номера вместе с кодом города или с кодом оператора равна точно 10 цифрам. Как заметили в комментариях коды городов «Уфа 347, Стерлитамак 3473, Агидель 34731» имеют разную длину, но в Уфе длина городского номера 7 цифр, в Стерлитамаке — 6, а в Агидели — 5, т. е. в сумме длина всегда 10 цифр.
Первые три цифры кода каждого из городов одинаковы — 347, и эти цифры можно назвать телефонным кодом региона в целом (по аналогии с КЛАДР, как это также заметили в комментариях). Для каждого региона России существует обычно один такой общий псевдокод региона, но в Москве их два — 499 и 495. Т. е. для всех регионов России существует менее 90 кодов (не настолько большая цифра, чтобы прибегать к услугам базы данных).
Распределение кодов регионов по карте России тоже имеет некоторые закономерности: 45х-49х — Центральная Россия, окруженная 81х — 87х (с севера на юг вторая цифра обычно увеличивается), в глубь страны идут 34х-39х, и Саха с Дальним Востоком имеют коды 41х-42х. Калининградская область («на отшибе») имеет код 401. Так что и на основании этих данных можно осуществить проверку правильности ввода телефонного номера.
Но не бывает правил «10 цифр (код+номер)» без исключений. Точно знаю, что в Московской области телефоны вида: (49645) х-хх-хх заменяются на (245) х-хх-хх (496 заменяется на 2), по другим регионам информации у меня нет.
Итак, регион находим по первым трем цифрам 10-значного номера, уточняем положение внутри региона добавляя еще 1 или 2 следующих цифры. Для корректного форматирования номера стационарного телефона уже придется иметь базу кодов городов, чтобы точно отделить номер от кода. Всего кодов российских городов в открытых источниках мне удалось найти более 2000.
Что касается кодов мобильных операторов, то по этому коду можно определять принадлежность номера к определенному региону. И если емкость 926 полностью принадлежит Москве и области, то в случае с 901 не все так просто, но не безнадежно. Например, (901)6000000 — (901)6009999 — это Респ. Хакасия (но не вся), а (901)9440000 — (901)9449999 — Архангельская область (тоже не вся). Для каждого региона может быть назначено несколько последовательностей (емкостей) внутри одного кода оператора. Впрочем, это уже не вопрос форматирования, т. к. длина номера с кодом и здесь — ровно 10 цифр.Общее число непрерывных последовательностей (регион, код, диапазон, дата открытия диапазона) в России более 3500, т. е. без базы данных проверить корректность номера и/или принадлежность к определенному региону также проблематично.
С уважением,
Илья
Здравствуйте, Александр!
На хабре не зарегистрирован, поэтому не могу прокомментировать статью Форматирование телефонных номеров на PHP, а контакты автора не нашел. Увидел, что Вы принимаете активное участие в обсуждении, поэтому написал Вам с просьбой опубликовать мой комментарий. Прошу прощения за беспокойство.
В России длина телефонного номера вместе с кодом города или с кодом оператора равна точно 10 цифрам. Как заметили в комментариях коды городов «Уфа 347, Стерлитамак 3473, Агидель 34731» имеют разную длину, но в Уфе длина городского номера 7 цифр, в Стерлитамаке — 6, а в Агидели — 5, т. е. в сумме длина всегда 10 цифр.
Первые три цифры кода каждого из городов одинаковы — 347, и эти цифры можно назвать телефонным кодом региона в целом (по аналогии с КЛАДР, как это также заметили в комментариях). Для каждого региона России существует обычно один такой общий псевдокод региона, но в Москве их два — 499 и 495. Т. е. для всех регионов России существует менее 90 кодов (не настолько большая цифра, чтобы прибегать к услугам базы данных).
Распределение кодов регионов по карте России тоже имеет некоторые закономерности: 45х-49х — Центральная Россия, окруженная 81х — 87х (с севера на юг вторая цифра обычно увеличивается), в глубь страны идут 34х-39х, и Саха с Дальним Востоком имеют коды 41х-42х. Калининградская область («на отшибе») имеет код 401. Так что и на основании этих данных можно осуществить проверку правильности ввода телефонного номера.
Но не бывает правил «10 цифр (код+номер)» без исключений. Точно знаю, что в Московской области телефоны вида: (49645) х-хх-хх заменяются на (245) х-хх-хх (496 заменяется на 2), по другим регионам информации у меня нет.
Итак, регион находим по первым трем цифрам 10-значного номера, уточняем положение внутри региона добавляя еще 1 или 2 следующих цифры. Для корректного форматирования номера стационарного телефона уже придется иметь базу кодов городов, чтобы точно отделить номер от кода. Всего кодов российских городов в открытых источниках мне удалось найти более 2000.
Что касается кодов мобильных операторов, то по этому коду можно определять принадлежность номера к определенному региону. И если емкость 926 полностью принадлежит Москве и области, то в случае с 901 не все так просто, но не безнадежно. Например, (901)6000000 — (901)6009999 — это Респ. Хакасия (но не вся), а (901)9440000 — (901)9449999 — Архангельская область (тоже не вся). Для каждого региона может быть назначено несколько последовательностей (емкостей) внутри одного кода оператора. Впрочем, это уже не вопрос форматирования, т. к. длина номера с кодом и здесь — ровно 10 цифр.Общее число непрерывных последовательностей (регион, код, диапазон, дата открытия диапазона) в России более 3500, т. е. без базы данных проверить корректность номера и/или принадлежность к определенному региону также проблематично.
С уважением,
Илья
+2
Большое спасибо за подробные разъяснения, в большинстве своем (за исключением привязки к регионам РФ) это все учтено в базе, которая прилагается к описанной функции.
Необходимые уточнения касательно внешнего форматирования, на который, как было обсуждено в комментариях, влияет относительное расположение звонящего, а также локально принятые нормы вывода телефона, будут внедрены в следующей версии кода, которой будет выделена отдельная статья с описанием изменений.
Необходимые уточнения касательно внешнего форматирования, на который, как было обсуждено в комментариях, влияет относительное расположение звонящего, а также локально принятые нормы вывода телефона, будут внедрены в следующей версии кода, которой будет выделена отдельная статья с описанием изменений.
0
Добавлю, что имею на руках справочник деления кодов по регионам, который будет использован для предоставления дополнительной информации по форматируемому номеру.
0
Илья прислал еще одно письмо:
цитата:
Два текстовых файла внутри архива. Сделал минут 20 назад.
dl.dropbox.com/u/8251541/tel_codes.rar
Эту ссылку можете дать на хабре, может, кому тоже пригодится. Заодно ошибки Ростелекомовские поищем вместе.
цитата:
Два текстовых файла внутри архива. Сделал минут 20 назад.
dl.dropbox.com/u/8251541/tel_codes.rar
Эту ссылку можете дать на хабре, может, кому тоже пригодится. Заодно ошибки Ростелекомовские поищем вместе.
+1
Вопрос о symfony (правильно пишется так) — где вы нашли этот хелпер?
В исходниках svn.symfony-project.com/branches/ его нет, и сам я его не помню тоже.
В исходниках svn.symfony-project.com/branches/ его нет, и сам я его не помню тоже.
0
Нашел в гугле сразу ссылку на страницу с кодом snippets.symfony-project.org/snippet/273
0
а как дела у дальнейшей поддержки этого скрипта?
0
Спасибо за проделанную работу, очень функционально и удобно, вот только в России больше нет кода «3432» это бывший код г. Екатеринбурга, сейчас «343» уже больше 2-х лет, коды «3434» и соответсвенно «3435» при этом есть.
Было бы отлично, если бы выложили на GitHub например, что бы можно было вносить такие правки в хеш, и соответсвенно сгружать саму актуальную версию.
Было бы отлично, если бы выложили на GitHub например, что бы можно было вносить такие правки в хеш, и соответсвенно сгружать саму актуальную версию.
0
Спасибо, очень годно, залепил класс и поставил себе за пару минут как говорится из коробки :)
0
Пост староват, но рискну выдвинуть предложение: форматировать номера можно с помощью гугловского порта libphonenumber: github.com/giggsey/libphonenumber-for-php
Не только форматировать, но еще и нормализовывать позволяет (типа 89261234567 => +79261234567). Я пользуюсь ей сейчас для нормализации введенных клиентами телефонных номеров.
Не только форматировать, но еще и нормализовывать позволяет (типа 89261234567 => +79261234567). Я пользуюсь ей сейчас для нормализации введенных клиентами телефонных номеров.
0
не читал, но вот вам сообщение из будущего, с моей наивной реализацией поиска телефонов в тексте:
document.documentElement.outerText
.match(/(\+?((\s|\(|\)|\-|)|\d+)+\d+)+/g)
.map((raw) => ({ raw, fmt: raw.replace(/\D/g, "") }))
.filter(({ fmt }) => fmt.length >= 9)
.map(({ raw, fmt }) => {
if (fmt.length === 11 && ["8", "7"].includes(fmt[0])) {
return { raw, fmt: `+7 (${fmt.slice(1, 4)}) ${fmt.slice(4, 7)}-${fmt.slice(7, 9)}-${fmt.slice(9, 11)}` };
}
if (fmt.length === 10 && "9" === fmt[0]) {
return { raw, fmt: `+7 (${fmt.slice(0, 3)}) ${fmt.slice(3, 6)}-${fmt.slice(6, 8)}-${fmt.slice(8, 10)}` };
}
})
.filter(Boolean);
не продакшен реди, но теперь мы можем взять raw и заменить его на fmt в тексте
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Форматирование телефонных номеров на PHP