Регулярное выражение для переформатирования номера телефона в США в Javascript

97

Я хочу переформатировать (заменить, а не проверять - есть много ссылок для проверки) номер телефона для отображения в Javascript. Вот пример некоторых данных:

  • 123 4567890
  • (123) 456-7890
  • (123)456-7890
  • 123 456 7890
  • 123.456.7890
  • (пусто / ноль)
  • 1234567890

Есть ли простой способ использовать для этого регулярное выражение? Я ищу лучший способ сделать это. Есть ли способ лучше?

Я хочу переформатировать это число в следующее: (123) 456-7890

Мэтт К.
источник
3
И какой из них ваш целевой формат?
До Хельге
Этот: (123) 456-7890
Мэтт К.
3
Я бы сказал, просто удалите все нецифровые символы, а затем возьмите три подстроки.
Wiseguy
2
@Wiseguy, пожалуйста, опубликуйте это как ответ (с примером), так как это действительно то, что OP должен делать.
Брайан Дрисколл,
1
Вам также необходимо указать, как каждый из принятых форматов сопоставляется с целевым форматом, что совсем не очевидно, если входной параметр равен нулю. Если вы не хотите использовать дополнительное условие, чтобы отсеять этот случай.
Джон

Ответы:

240

Предполагая, что вам нужен формат " (123) 456-7890":

function formatPhoneNumber(phoneNumberString) {
  var cleaned = ('' + phoneNumberString).replace(/\D/g, '')
  var match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/)
  if (match) {
    return '(' + match[1] + ') ' + match[2] + '-' + match[3]
  }
  return null
}

Вот версия, которая позволяет использовать дополнительный +1международный код:

function formatPhoneNumber(phoneNumberString) {
  var cleaned = ('' + phoneNumberString).replace(/\D/g, '')
  var match = cleaned.match(/^(1|)?(\d{3})(\d{3})(\d{4})$/)
  if (match) {
    var intlCode = (match[1] ? '+1 ' : '')
    return [intlCode, '(', match[2], ') ', match[3], '-', match[4]].join('')
  }
  return null
}
formatPhoneNumber('+12345678900') // => "+1 (234) 567-8900"
formatPhoneNumber('2345678900')   // => "(234) 567-8900"
maerics
источник
2
Отлично; Спасибо! Однако после добавления этой функции я изменил return (!m) ? nullна return (!m) ? "".
Matt K
2
Хороший урок того, как подойти к проблеме. Я пытался придумать, как сопоставить все возможные случаи - вы исключите несущественное и посмотрите, есть ли совпадение. Очень хорошо.
Jkleg
2
К вашему сведению, это не работает для таких номеров, как + 1555-555-5555
Will
'' + phoneNumberStringто же самое, что phoneNumberString... Это уже строка.
YungGun
@YungGun, если кто-то не вызывает функцию с номером, напримерformatPhoneNumber(8001231234)
maerics
32

Возможное решение:

function normalize(phone) {
    //normalize string and remove all unnecessary characters
    phone = phone.replace(/[^\d]/g, "");

    //check if number length equals to 10
    if (phone.length == 10) {
        //reformat and return phone number
        return phone.replace(/(\d{3})(\d{3})(\d{4})/, "($1) $2-$3");
    }

    return null;
}

var phone = '(123)4567890';
phone = normalize(phone); //(123) 456-7890
ioseb
источник
27

var x = '301.474.4062';
    
x = x.replace(/\D+/g, '')
     .replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');

alert(x);

Шон Брайт
источник
1
Спасибо, Шон, мне нравится ваше короткое простое встроенное решение.
user752746 02
1
Спасибо за это! Я изменил его на, например, x = x.replace(/[^\d]+/g, '') .replace(/(\d{1})(\d{3})(\d{3})(\d{4})/, '+$1 ($2) $3-$4');для добавления «+1» перед номером телефона
Greg A
Благодарность! это как раз мне нужно
Альберт Идальго
8

Этот ответ заимствован из ответа Maerics. Он отличается прежде всего тем, что принимает частично введенные телефонные номера и форматирует введенные части.

phone = value.replace(/\D/g, '');
const match = phone.match(/^(\d{1,3})(\d{0,3})(\d{0,4})$/);
if (match) {
  phone = `${match[1]}${match[2] ? ' ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}`;
}
return phone
Дэвид Баукум
источник
Это работает по мере того, как вы печатаете, добавляя в желаемом формате из исходного плаката. После 1,5 часов поиска я счастлив, что попробовал эту!
фунгусантракс
Я добавил скобки вокруг кода города, если это помогает:(${match[1]}${match[2] ? ') ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}
Питер Холлингсворт,
На самом деле проблема в том, что вы не можете вернуться назад через '-' или пробел от середины строки. Вам необходимо предотвратить переформатирование, когда пользователь выполняет обратный интервал (например, newstring.length < oldstring.lengthИЛИ, чтобы отслеживать положение курсора и выяснять, когда пользователь только что отступил на эти разделители, напримерif (cursorPosition === 4 && numericString.length > 3)
Питер Холлингсворт,
В моем коде реакции я обхожу это, сохраняя внутри только введенное число, а затем форматируя то, что помещается в поле. Таким образом, возврат удаляет предыдущий символ в фактическом значении, а не в отображаемом значении.
Дэвид Баукум,
5

Я использую эту функцию для форматирования номеров США.

function formatUsPhone(phone) {

    var phoneTest = new RegExp(/^((\+1)|1)? ?\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})( ?(ext\.? ?|x)(\d*))?$/);

    phone = phone.trim();
    var results = phoneTest.exec(phone);
    if (results !== null && results.length > 8) {

        return "(" + results[3] + ") " + results[4] + "-" + results[5] + (typeof results[8] !== "undefined" ? " x" + results[8] : "");

    }
    else {
         return phone;
    }
}

Он принимает почти все мыслимые способы написания телефонного номера в США. Результат отформатирован в стандартную форму (987) 654-3210 x123.

микрыз
источник
3

думать задом наперед

Принимайте только последние цифры (до 10), игнорируя первую «1».

function formatUSNumber(entry = '') {
  const match = entry
    .replace(/\D+/g, '').replace(/^1/, '')
    .match(/([^\d]*\d[^\d]*){1,10}$/)[0]
  const part1 = match.length > 2 ? `(${match.substring(0,3)})` : match
  const part2 = match.length > 3 ? ` ${match.substring(3, 6)}` : ''
  const part3 = match.length > 6 ? `-${match.substring(6, 10)}` : ''    
  return `${part1}${part2}${part3}`
}

пример ввода / вывода при вводе

formatUSNumber('+1333')
// (333)

formatUSNumber('333')
// (333)

formatUSNumber('333444')
// (333) 444

formatUSNumber('3334445555')
// (333) 444-5555
Джейсон Себринг
источник
1
var numbers = "(123) 456-7890".replace(/[^\d]/g, ""); //This strips all characters that aren't digits
if (numbers.length != 10) //wrong format
    //handle error
var phone = "(" + numbers.substr(0, 3) + ") " + numbers.substr(3, 3) + "-" + numbers.substr(6); //Create format with substrings
Алекс Терпин
источник
1

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

Вот решение jquery, которое обрабатывает это, а также гарантирует, что курсор остается в нужном месте во время редактирования:

//format text input as phone number (nnn) nnn-nnnn
$('.myPhoneField').on('input', function (e){
    var $phoneField = e.target;
    var cursorPosition = $phoneField.selectionStart;
    var numericString = $phoneField.value.replace(/\D/g, '').substring(0, 10);

    // let user backspace over the '-'
    if (cursorPosition === 9 && numericString.length > 6) return;

    // let user backspace over the ') '
    if (cursorPosition === 5 && numericString.length > 3) return;
    if (cursorPosition === 4 && numericString.length > 3) return;

    var match = numericString.match(/^(\d{1,3})(\d{0,3})(\d{0,4})$/);
    if (match) {
        var newVal = '(' + match[1];
        newVal += match[2] ? ') ' + match[2] : '';
        newVal += match[3] ? '-' + match[3] : '';

        // to help us put the cursor back in the right place
        var delta = newVal.length - Math.min($phoneField.value.length, 14);      
        $phoneField.value = newVal;
        $phoneField.selectionEnd = cursorPosition + delta;
    } else {
        $phoneField.value = '';        
    }
})
Питер Холлингсворт
источник
0

Вот тот, который принимает как номера телефонов, так и номера телефонов с добавочными номерами.

function phoneNumber(tel) {
var toString = String(tel),
    phoneNumber = toString.replace(/[^0-9]/g, ""),
    countArrayStr = phoneNumber.split(""),
    numberVar = countArrayStr.length,
    closeStr = countArrayStr.join("");
if (numberVar == 10) {
    var phone = closeStr.replace(/(\d{3})(\d{3})(\d{4})/, "$1.$2.$3"); // Change number symbols here for numbers 10 digits in length. Just change the periods to what ever is needed.
} else if (numberVar > 10) {
    var howMany = closeStr.length,
        subtract = (10 - howMany),
        phoneBeginning = closeStr.slice(0, subtract),
        phoneExtention = closeStr.slice(subtract),
        disX = "x", // Change the extension symbol here
        phoneBeginningReplace = phoneBeginning.replace(/(\d{3})(\d{3})(\d{4})/, "$1.$2.$3"), // Change number symbols here for numbers greater than 10 digits in length. Just change the periods and to what ever is needed. 
        array = [phoneBeginningReplace, disX, phoneExtention],
        afterarray = array.splice(1, 0, " "),
        phone = array.join("");

} else {
    var phone = "invalid number US number";
}
return phone;
}

phoneNumber("1234567891"); // Your phone number here
Джонс
источник
0

Вы можете использовать эти функции для проверки действительных телефонных номеров и их нормализации:

let formatPhone = (dirtyNumber) => {
 return dirtyNumber.replace(/\D+/g, '').replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
}

let isPhone = (phone) => {
   //normalize string and remove all unnecessary characters
   phone = phone.replace(/\D+/g, '');
   return phone.length == 10? true : false;
}
Роднье Боррего Клаверо
источник
0

Я расширил ответ Дэвида Баукума, включив поддержку расширений длиной до 4 цифр. Он также включает круглые скобки, запрошенные в исходном вопросе. Это форматирование будет работать при вводе в поле.

phone = phone.replace(/\D/g, '');
const match = phone.match(/^(\d{1,3})(\d{0,3})(\d{0,4})(\d{0,4})$/);
if (match) {
    phone = `(${match[1]}${match[2] ? ') ' : ''}${match[2]}${match[3] ? '-' : ''}${match[3]}${match[4] ? ' x' : ''}${match[4]}`;
}
return phone;
Джереми
источник
0

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

Я наткнулся на этот пост в поисках чего-то, что можно было бы использовать с приложением для очистки текста, которое имеет возможности PCRE Regex (но не java-функции). Я опубликую это здесь для людей, которые могли бы использовать простое решение на чистом Regex, которое могло бы работать во множестве текстовых редакторов, очистителей, расширителей или даже некоторых менеджеров буфера обмена. Я лично использую Sublime и TextSoap. Это решение было разработано для текстового мыла, поскольку оно находится в строке меню и предоставляет раскрывающееся меню, в котором вы можете запускать действия по манипулированию текстом над тем, что выбрано курсором или что находится в буфере обмена.

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

Замена / поиск и замена # 1

  • Первая подстановка / поиск и замена удаляет нечисловые числа из 10-значного числа в 10-значную строку.

Первая замена / регулярное выражение поиска :\D

  • Эта строка поиска соответствует всем символам , что является не цифра.

Первая подстановка / замена регулярного выражения: "" (ничего, даже пробел)

  • Оставьте поле замены полностью пустым, пробелов не должно быть. Это приведет к удалению всех совпавших нецифровых символов. Перед этой операцией вы должны были ввести 10 цифр + символы форматирования и получить 10 цифр без символов форматирования.

Замена / поиск и замена # 2

  • Вторая замена / поиск и замена поиск части операции захваты группы для кода области $1, улавливающей группы для второго набора из трех чисел $2, а последний захват группы за последний набор из четырех чисел $3. Регулярное выражение для замещающей части операции вставляет форматирование номера телефона в США между захваченной группой цифр.

Вторая замена / регулярное выражение поиска :(\d{3})(\d{3})(\d{4})

Вторая подстановка / замена регулярного выражения:\($1\) $2\-$3

  • Обратный слэш \экранирует специальные символы (, ), (<-whitespace), и -так как мы вставляя их между нашими захваченными числами в группах захвата $1, $2, и $3для целей форматирования номера телефона в США.

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

Адамлоган
источник
-2

Для номеров телефонов в США

/^\(?(\d{3})\)?[- ]?(\d{3})[- ]?(\d{4})$/

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

  • /^\(?: Означает, что номер телефона может начинаться с необязательного (.
  • (\d{3}): После необязательного (должны быть 3 цифры. Если в номере телефона нет символа (, он должен начинаться с трех цифр. Например, (308или 308.
  • \)?: Означает, что номер телефона может содержать необязательные символы )после первых трех цифр.
  • [- ]?: Далее номер телефона может иметь дефис ( -) )после первых трех цифр, если он присутствует.
  • (\d{3}): Тогда должно быть еще 3 цифры. Например, (308)-135или 308-135или308135
  • [- ]?: После второго набора из 3 цифр номер телефона может иметь еще один необязательный дефис ( -). Например, (308)-135-или 308-135-или308135-
  • (\d{4})$/: Наконец, номер телефона должен заканчиваться четырьмя цифрами. Например, (308)-135-7895или 308-135-7895или 308135-7895или 3081357895.

    Справка :

http://www.zparacha.com/phone_number_regex/

Бебу
источник
1
Копирование материалов с других веб-сайтов, а затем даже отказ от
до Хельге
1
Извините, я понятия не имел, что мы должны разместить ссылку. Я думал, нам нужно просто дать ответы на опубликованные вопросы.
Bebu
5
Ни разу не нормально , чтобы сделать еще один чей вид работы , как свой собственный. В следующий раз помните, что в размещении ссылок нет ничего плохого, а в копировании (особенно без предоставления ссылки) - нет. И у вас всегда есть возможность отредактировать свой ответ.
До Хельге
Проголосовали против, потому что автор не ответил, как заменить номер телефона, как просил автор.
BrianHVB