Повторное выражение Javascript для проверки подлинности электронной почты в стиле GMail

Мне нужно регулярное выражение, которое будет принимать корректные электронные письма в нескольких форматах (см. ниже), которые будут введены в список, разделенный запятыми. У меня есть основной адрес электронной почты регулярное выражение проверки,

^[\w\d._%+-][email protected](?:[\w\d-]+\.)+(\w{2,})(,|$) 

который может обрабатывать тестовые примеры A и B, но не другие. Я также пробовал

^(\<)?[\w\d._%+-][email protected](?:[\w\d-]+\.)+(\w{2,})(\>)?(,|$)

который смог обрабатывать A, B и C, но только подтвердил первый адрес электронной почты в каждом из тестовых случаев D и E. Я даже не получил тестирование регулярного выражения для формата 3.

tl; dr Требуется регулярное выражение, которое будет проверять адреса электронной почты 1, 2 и 3.

Хороший сайт для проверки ваших регулярных выражений: Онлайн-тестер Javascript Regex Tester

Данные

Испытательные случаи
 A. [email protected]
 B. [email protected], [email protected]
 C. <[email protected]>, [email protected]
 D. <[email protected]>, <[email protected]>
 E. [email protected], <[email protected]>

Форматы адресов электронной почты
 1. [email protected]
 2. <[email protected]>
 3. "xyz" <[email protected]>

ИЗМЕНИТЬ

Я отметил это как возможный дубликат:

Проверить адрес электронной почты на JavaScript?

который, в свою очередь, представляется дубликатом:

Использование регулярного выражения для проверки адреса электронной почты

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

Ответ 1

Ни один из ссылок или ответов не был лучшим ответом на этот вопрос. Вот что это решило:

/*
* regex checks: must start with the beginning of a word or a left caret
* must end with either the end of a word or a right caret
* can handle example.example.com as possible domain
* email username can have + - _ and .
* not case sensitive
*/
var EMAIL_REGEX = /(\<|^)[\w\d._%+-][email protected](?:[\w\d-]+\.)+(\w{2,})(\>|$)/i;  
var emails = emailList.trim().split(',');  
var validEmails = [];  
var invalidEmails = [];  

for (var i = 0; i < emails.length; i++) {  
    var current = emails[i].trim();
    if(current !== "") {
        //if something matching the regex can be found in the string
        if(current.search(EMAIL_REGEX) !== -1) {
            //check if it has either a front or back bracket
            if(current.indexOf("<") > -1 || current.indexOf(">") > -1) {
                //if it has both, find the email address in the string
                if(current.indexOf("<") > -1 && current.indexOf(">") > -1) {
                    current = current.substr(current.indexOf("<")+1, current.indexOf(">")-current.indexOf("<") -1);
                } 
            } 
        }
        if(EMAIL_REGEX.test(current)) {
            validEmails.push(current);
        } else {
            invalidEmails.push(current);
        }
    }               
}

Ответ 2

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

Предположим, вы сделали это с помощью раскола

var bits = csv.split(',');

Итерации через массив bits

for (var i = 0; i < bits.length; ++i) {
  if (!validateEmail(bits[i])) {
    alert("Email #" + (i+1) + " is bogus");
  }
}

Тогда для регулярного выражения что-то вроде этого будет захватывать 2 и 3

(\"[a-z0-9\s]+\"\s+)?\<[\w\d._%+-][email protected](?:[\w\d-]+\.)+(\w{2,})\>

И вы можете использовать более простой способ для записи простых адресов электронной почты без < или имени в кавычках перед ним.

Одно регулярное выражение не обязательно будет запускаться быстрее, чем два теста if, особенно если вы коротко замыкаете or, поставив более вероятный первый. Это также труднее читать и поддерживать. Наконец, это довольно сложно, потому что вам нужен просмотр: окончательный > только в порядке, если строка перед адресом электронной почты содержит < прямо перед первым символом письма.

Так что мои $0.02 = не стоит. Просто выполните два регулярных выражения.

Ответ 3

Эта функция validateEmail проверяет базовый синтаксис адреса электронной почты ([email protected]). Включенный if будет проверять альтернативное форматирование (<[email protected]>, 'xyz' <[email protected]>) и проверять только фактическую часть электронной почты. Элементы с только < или > считаются недействительными для плохого форматирования ([email protected]>), то же самое с любыми сообщениями электронной почты, которым не требуется основная структура (invalidExample.com).

var emailList = "[email protected],<[email protected]>,'xyz' <[email protected]>,invalidExample.com,[email protected]>,'Still93e-=48%5922=2 Good' <[email protected]>";
var emails = emailList.split(",");

//Loop through the array of emails
for (var i = 0; i < emails.length; i++) {
    var isValid = 1;
    var cur = emails[i];

    // If it has a < or a >,
    if( cur.indexOf("<") > -1 || cur.indexOf(">") > -1 ){
        // Set it invalid
        isValid = 0;
        // But if it has both < and >
        if( cur.indexOf("<") > -1 && cur.indexOf(">") > -1 ){
            //Set it valid and set the cur email to the content between < and >
            isValid = 1;
            cur = cur.substr(cur.indexOf("<")+1, ( cur.indexOf(">") - cur.indexOf("<") - 1 ));
        }
    }
    //Run the validate function
    if ( !validateEmail(cur) )
        isValid = 0;

    // Output your results. valid = 1, not valid = 0
    alert("Orig: "+emails[i] +"\nStripped: "+cur+"\nIs Valid: "+isValid);

}

function validateEmail(curEmail){
    var emailValid = /.*\@.*\..*$/g;
    return (curEmail.test(emailValid));
}

jsFiddle

Ответ 4

Помогло ли что-то подобное?

Я тестировал 2. и 3., и он обнаруживает оба шаблона.

var isEmail_re       = /^\s*[\w\-\+_]+(\.[\w\-\+_]+)*\@[\w\-\+_]+\.[\w\-\+_]+(\.[\w\-\+_]+)*\s*$/;

function isEmail (s) {
   return String(s).search (isEmail_re) != -1;
}

alert(isEmail ('"xyz"<[email protected]>'));

http://jsfiddle.net/epinapala/BfKrR/