Комплексное регулярное выражение для проверки номера телефона - PullRequest
874 голосов
/ 24 сентября 2008

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

  • 1-234-567-8901
  • 1-234-567-8901 x1234
  • 1-234-567-8901 ext1234
  • 1 (234) 567-8901
  • 1.234.567.8901
  • 12345678901

Я отвечу своей текущей попыткой, но я надеюсь, что у кого-то есть что-то лучше и / или более элегантно.

Ответы [ 39 ]

6 голосов
/ 24 сентября 2008

Я считаю, что Номер :: Телефон :: США и Regexp :: Common (в частности, источник Regexp :: Common :: URI :: RFC2806 ) Модули Perl могут помочь.

Вопрос, вероятно, должен быть определен более подробно, чтобы объяснить цель проверки чисел. Например, 911 является действительным числом в США, но 911x не для любого значения х. Это так, что телефонная компания может рассчитать, когда вы закончите набор номера. Есть несколько вариантов по этому вопросу. Но ваше регулярное выражение не проверяет часть кода города, так что это не выглядит проблемой.

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

Если вы пытаетесь проверить ввод пользователя, почему бы не нормализовать результат и покончить с этим? Если пользователь вводит номер, который вы не можете распознать как действительный номер, либо сохраните его как введенный, либо удалите недоступные символы. Модуль Number :: Phone :: Normalize может быть источником вдохновения.

4 голосов
/ 24 сентября 2008

Я работаю в компании, занимающейся исследованиями рынка, и мы должны фильтровать эти типы входных данных все время. Ты слишком усложняешь это. Просто удалите не алфавитно-цифровые символы и посмотрите, есть ли расширение.

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

4 голосов
/ 21 июля 2009

Сделайте замену символов форматирования, затем проверьте оставшиеся на правильность номера телефона. В PHP

 $replace = array( ' ', '-', '/', '(', ')', ',', '.' ); //etc; as needed
 preg_match( '/1?[0-9]{10}((ext|x)[0-9]{1,4})?/i', str_replace( $replace, '', $phone_num );

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

3 голосов
/ 21 июля 2009

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

Сценарий наихудшего случая, если пользователь должен был извлечь неформатированный номер из файла XML, он все равно просто набрал бы цифры на цифровой клавиатуре телефона 012345678x5, и нет никакой реальной причины сохранять его красивым. Такой RegEx будет для меня примерно таким:

\d+ ?\w{0,9} ?\d+
  • 01234467 extension 123456
  • 01234567x123456
  • 01234567890
3 голосов
/ 04 января 2011

Я обнаружил, что это что-то интересное. Я не проверял это, но похоже, что это будет работать

<?php
/*
string validate_telephone_number (string $number, array $formats)
*/

function validate_telephone_number($number, $formats)
{
$format = trim(ereg_replace("[0-9]", "#", $number));

return (in_array($format, $formats)) ? true : false;
}

/* Usage Examples */

// List of possible formats: You can add new formats or modify the existing ones

$formats = array('###-###-####', '####-###-###',
                 '(###) ###-###', '####-####-####',
                 '##-###-####-####', '####-####', '###-###-###',
                 '#####-###-###', '##########');

$number = '08008-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '123-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1800-1234-5678';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '(800) 555-123';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1234567890';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}
?>
3 голосов
/ 13 мая 2012

Вот тот, который хорошо работает в JavaScript. Это в строке, потому что это то, что ожидал виджет Dojo.

Соответствует 10-значному номеру NANP Северной Америки с дополнительным добавочным номером. Пробелы, тире и точки являются допустимыми разделителями.

"^(\\(?\\d\\d\\d\\)?)( |-|\\.)?\\d\\d\\d( |-|\\.)?\\d{4,4}(( |-|\\.)?[ext\\.]+ ?\\d+)?$"
3 голосов
/ 11 августа 2011

Возможно, для этого вам лучше использовать замаскированный ввод. Таким образом, пользователи могут вводить цифры ТОЛЬКО, а вы можете форматировать их так, как считаете нужным. Я не уверен, если это для веб-приложения, но если это так, есть плагин jQuery очень щелчок, который предлагает некоторые варианты для этого.

http://digitalbush.com/projects/masked-input-plugin/

Они даже рассказывают, как маскировать ввод телефонных номеров в своем уроке.

2 голосов
/ 01 марта 2011
    pattern="^[\d|\+|\(]+[\)|\d|\s|-]*[\d]$" 
    validateat="onsubmit"

Должен заканчиваться цифрой, может начинаться с (или + или цифры и может содержать + - (или)

2 голосов
/ 24 сентября 2008

Я склонен согласиться с тем, что убираем не-цифры и просто принимаем то, что есть, лучше всего. Может быть, чтобы убедиться, что есть хотя бы пара цифр, хотя это запрещает что-то вроде буквенного номера телефона "ASK-JAKE", например.

Может быть несколько простых выражений perl:

@f = /(\d+)/g;
tr/0-9//dc;

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

Есть ли опасения, что может потребоваться пауза, а затем ввести больше ключей? Или что-то вроде 555-1212 (подайте звуковой сигнал) 123?

2 голосов
/ 09 августа 2011

Для тех, кто заинтересован в том, чтобы сделать что-то подобное с ирландскими номерами мобильных телефонов, вот простой способ сделать это:

http://ilovenicii.com/?p=87

PHP


<?php
$pattern = "/^(083|086|085|086|087)\d{7}$/";
$phone = "087343266";

if (preg_match($pattern,$phone)) echo "Match";
else echo "Not match";

По этой ссылке также есть решение JQuery.

EDIT:

Решение jQuery:

    $(function(){
    //original field values
    var field_values = {
            //id        :  value
            'url'       : 'url',
            'yourname'  : 'yourname',
            'email'     : 'email',
            'phone'     : 'phone'
    };

        var url =$("input#url").val();
        var yourname =$("input#yourname").val();
        var email =$("input#email").val();
        var phone =$("input#phone").val();


    //inputfocus
    $('input#url').inputfocus({ value: field_values['url'] });
    $('input#yourname').inputfocus({ value: field_values['yourname'] });
    $('input#email').inputfocus({ value: field_values['email'] }); 
    $('input#phone').inputfocus({ value: field_values['phone'] });



    //reset progress bar
    $('#progress').css('width','0');
    $('#progress_text').html('0% Complete');

    //first_step
    $('form').submit(function(){ return false; });
    $('#submit_first').click(function(){
        //remove classes
        $('#first_step input').removeClass('error').removeClass('valid');

        //ckeck if inputs aren't empty
        var fields = $('#first_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<12 || value==field_values[$(this).attr('id')] ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }
        });        

        if(!error) {
            if( $('#password').val() != $('#cpassword').val() ) {
                    $('#first_step input[type=password]').each(function(){
                        $(this).removeClass('valid').addClass('error');
                        $(this).effect("shake", { times:3 }, 50);
                    });

                    return false;
            } else {   
                //update progress bar
                $('#progress_text').html('33% Complete');
                $('#progress').css('width','113px');

                //slide steps
                $('#first_step').slideUp();
                $('#second_step').slideDown();     
            }               
        } else return false;
    });

    //second section
    $('#submit_second').click(function(){
        //remove classes
        $('#second_step input').removeClass('error').removeClass('valid');

        var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;  
        var fields = $('#second_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<1 || value==field_values[$(this).attr('id')] || ( $(this).attr('id')=='email' && !emailPattern.test(value) ) ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }


        function validatePhone(phone) {
        var a = document.getElementById(phone).value;
        var filter = /^[0-9-+]+$/;
            if (filter.test(a)) {
                return true;
            }
            else {
                return false;
            }
        }

        $('#phone').blur(function(e) {
            if (validatePhone('txtPhone')) {
                $('#spnPhoneStatus').html('Valid');
                $('#spnPhoneStatus').css('color', 'green');
            }
            else {
                $('#spnPhoneStatus').html('Invalid');
            $('#spnPhoneStatus').css('color', 'red');
            }
        });

     });

        if(!error) {
                //update progress bar
                $('#progress_text').html('66% Complete');
                $('#progress').css('width','226px');

                //slide steps
                $('#second_step').slideUp();
                $('#fourth_step').slideDown();     
        } else return false;

    });


    $('#submit_second').click(function(){
        //update progress bar
        $('#progress_text').html('100% Complete');
        $('#progress').css('width','339px');

        //prepare the fourth step
        var fields = new Array(
            $('#url').val(),
            $('#yourname').val(),
            $('#email').val(),
            $('#phone').val()

        );
        var tr = $('#fourth_step tr');
        tr.each(function(){
            //alert( fields[$(this).index()] )
            $(this).children('td:nth-child(2)').html(fields[$(this).index()]);
        });

        //slide steps
        $('#third_step').slideUp();
        $('#fourth_step').slideDown();            
    });


    $('#submit_fourth').click(function(){

        url =$("input#url").val();
        yourname =$("input#yourname").val();
        email =$("input#email").val();
        phone =$("input#phone").val();

        //send information to server
        var dataString = 'url='+ url + '&yourname=' + yourname + '&email=' + email + '&phone=' + phone;  



        alert (dataString);//return false;  
            $.ajax({  
                type: "POST",  
                url: "http://clients.socialnetworkingsolutions.com/infobox/contact/",  
                data: "url="+url+"&yourname="+yourname+"&email="+email+'&phone=' + phone,
                cache: false,
                success: function(data) {  
                    console.log("form submitted");
                    alert("success");
                }
                });  
        return false;

   });


    //back button
    $('.back').click(function(){
        var container = $(this).parent('div'),
        previous  = container.prev();

        switch(previous.attr('id')) {
            case 'first_step' : $('#progress_text').html('0% Complete');
                  $('#progress').css('width','0px');
                       break;
            case 'second_step': $('#progress_text').html('33% Complete');
                  $('#progress').css('width','113px');
                       break;

            case 'third_step' : $('#progress_text').html('66% Complete');
                  $('#progress').css('width','226px');
                       break;

        default: break;
    }

    $(container).slideUp();
    $(previous).slideDown();
});


});

Источник .

...