Я также предложил бы посмотреть в библиотеке Google libphonenumber . Я знаю, что это не регулярное выражение, но оно делает именно то, что вы хотите.
Например, он распознает, что:
15555555555
- это возможное число, но не действительное число. Он также поддерживает страны за пределами США.
Основные функции:
getNumberType
- получает тип числа, основанного на самом номере; isNumberMatch
- получает уровень уверенности в том, могут ли два числа быть getExampleNumber
/ getExampleNumberByType
- предоставляет действительные номера примеров для всех стран / регионов, с возможностью указать, какой тип номера номера телефона необходим. isPossibleNumber
- быстро угадывая, является ли число возможным номером звонка, используя только информацию о длине, намного быстрее, чем полная проверка. isValidNumber
- полная проверка номера телефона для региона с использованием информации о длине и префиксе . AsYouTypeFormatter
- форматирует номера телефонов «на лету», когда пользователи вводят каждую цифру. findNumbers
- находит номера в текстовом вводе. PhoneNumberOfflineGeocoder
- предоставляет географическую информацию, относящуюся к номеру телефона. Самая большая проблема с проверкой номера телефона - это очень культурная зависимость.
(408) 974–2042
является действительным Номер в США (999) 974–2042
не является допустимым номером в США 0404 999 999
является действительным австралийским номером (02) 9999 9999
, также является действительным австралийским номером (09) 9999 9999
, не является действительным австралийским номером Регулярное выражение отлично подходит для проверки формата номера телефона, но на самом деле не будет возможности проверить действительность номера телефона.
Я бы предложил пропустить простое регулярное выражение, чтобы проверить ваш номер телефона, и использовать библиотеку, такую как libphonenumber
Google [ссылка на проект GitHub] .
Используя один из ваших более сложных примеров, 1-234-567-8901 x1234
, вы получаете следующие данные из libphonenumber
(ссылка на онлайн-демонстрацию) :
Validation Results
Result from isPossibleNumber() true
Result from isValidNumber() true
Formatting Results:
E164 format +12345678901
Original format (234) 567-8901 ext. 123
National format (234) 567-8901 ext. 123
International format +1 234-567-8901 ext. 123
Out-of-country format from US 1 (234) 567-8901 ext. 123
Out-of-country format from CH 00 1 234-567-8901 ext. 123
Таким образом, вы не только узнаете, действительно ли номер телефона (какой он есть), но также вы получаете согласованную форму номера телефона
В качестве бонуса, libphonenumber
имеет ряд наборов данных для проверки правильности номеров телефонов, поэтому, проверяя число, например +61299999999
(международная версия (02) 9999 9999
) возвращает в качестве допустимого числа с форматированием:
Validation Results
Result from isPossibleNumber() true
Result from isValidNumber() true
Formatting Results
E164 format +61299999999
Original format 61 2 9999 9999
National format (02) 9999 9999
International format +61 2 9999 9999
Out-of-country format from US 011 61 2 9999 9999
Out-of-country format from CH 00 61 2 9999 9999
libphonenumber также дает вам много дополнительных преимуществ, таких как захват местоположения, в котором обнаружен номер телефона, а также получить информацию о часовом поясе с номера телефона:
PhoneNumberOfflineGeocoder Results
Location Australia
PhoneNumberToTimeZonesMapper Results
Time zone(s) [Australia/Sydney]
Но неверный номер австралийского телефона ( (09) 9999 9999
) показывает, что он не является действительным номером телефона.
Validation Results
Result from isPossibleNumber() true
Result from isValidNumber() false
Версия Google имеет код для Java и Javascript, но люди также реализовали библиотеки для других языков, которые используют набор данных телефона i18n для Google:
Если вы не уверены, что находитесь всегда собираюсь принимать номера из одной локали, и они всегда будут в одном формате, я бы сильно предложил не писать собственный код для этого и использовать libphonenumber для проверки и отображения номеров телефонов.
Из 8.3.6 ([dcl.fct.default]) / 3:
Аргумент по умолчанию не указывается для пакета параметров.
blockquote>Из 8.3.6 ([dcl.fct.default]) / 4:
В объявлении данной функции каждый параметр, следующий за параметром с аргументом по умолчанию, должен иметь аргумент по умолчанию, предоставленный в этом или предыдущем объявлении или будет пакетом параметров функции.
blockquote>Таким образом, это позволяет использовать код, например
void f(int a = 10, Args ... args)
, или как ваш первый фрагмент. (Спасибо @ T.C. для поиска второго предложения!) [/ G4]
Kerrek SB говорит, что это невозможно. Вместо этого вы можете использовать std::tuple
template <class ... Args>
void foo( std::tuple<Args...> t = std::tuple<int>(0) )
{}