Проверка идентификатора электронной почты в соответствии с RFC5322 и https://en.wikipedia.org/wiki/Email_address - PullRequest
0 голосов
/ 14 ноября 2018

Проверка идентификаторов электронной почты согласно RFC5322 и следующим

https://en.wikipedia.org/wiki/Email_address

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

public void checkValid() {
    List<String> emails = new ArrayList();
    //Valid Email Ids
    emails.add("simple@example.com");
    emails.add("very.common@example.com");                   
    emails.add("disposable.style.email.with+symbol@example.com");
    emails.add("other.email-with-hyphen@example.com");
    emails.add("fully-qualified-domain@example.com");
    emails.add("user.name+tag+sorting@example.com");
    emails.add("fully-qualified-domain@example.com");
    emails.add("x@example.com");
    emails.add("carlosd'intino@arnet.com.ar");
    emails.add("example-indeed@strange-example.com");
    emails.add("admin@mailserver1");
    emails.add("example@s.example");
    emails.add("\" \"@example.org");
    emails.add("\"john..doe\"@example.org");

    //Invalid emails Ids
    emails.add("Abc.example.com");
    emails.add("A@b@c@example.com");
    emails.add("a\"b(c)d,e:f;g<h>i[j\\k]l@example.com");
    emails.add("just\"not\"right@example.com");
    emails.add("this is\"not\\allowed@example.com");
    emails.add("this\\ still\"not\\allowed@example.com");
                    emails.add("1234567890123456789012345678901234567890123456789012345678901234+x@example.com");
    emails.add("john..doe@example.com");
    emails.add("john.doe@example..com");

    String regex = "^[a-zA-Z0-9_!#$%&'*+/=? \\\"`{|}~^.-]+@[a-zA-Z0-9.-]+$";

    Pattern pattern = Pattern.compile(regex);
    int i=0;
    for(String email : emails){
        Matcher matcher = pattern.matcher(email);
        System.out.println(++i +"."+email +" : "+ matcher.matches());
    }
}

Фактический объем производства:

   1.simple@example.com : true
   2.very.common@example.com : true
   3.disposable.style.email.with+symbol@example.com : true
   4.other.email-with-hyphen@example.com : true
   5.fully-qualified-domain@example.com : true
   6.user.name+tag+sorting@example.com : true
   7.fully-qualified-domain@example.com : true
   8.x@example.com : true
   9.carlosd'intino@arnet.com.ar : true
   10.example-indeed@strange-example.com : true
   11.admin@mailserver1 : true
   12.example@s.example : true
   13." "@example.org : true
   14."john..doe"@example.org : true
   15.Abc.example.com : false
   16.A@b@c@example.com : false
   17.a"b(c)d,e:f;g<h>i[j\k]l@example.com : false
   18.just"not"right@example.com : true
   19.this is"not\allowed@example.com : false
   20.this\ still"not\allowed@example.com : false
   21.1234567890123456789012345678901234567890123456789012345678901234+x@example.com    : true
   22.john..doe@example.com : true
   23.john.doe@example..com : true

Ожидаемый выход:

1.simple@example.com : true
2.very.common@example.com : true
3.disposable.style.email.with+symbol@example.com : true
4.other.email-with-hyphen@example.com : true
5.fully-qualified-domain@example.com : true
6.user.name+tag+sorting@example.com : true
7.fully-qualified-domain@example.com : true
8.x@example.com : true
9.carlosd'intino@arnet.com.ar : true
10.example-indeed@strange-example.com : true
11.admin@mailserver1 : true
12.example@s.example : true
13." "@example.org : true
14."john..doe"@example.org : true
15.Abc.example.com : false
16.A@b@c@example.com : false
17.a"b(c)d,e:f;g<h>i[j\k]l@example.com : false
18.just"not"right@example.com : false
19.this is"not\allowed@example.com : false
20.this\ still"not\allowed@example.com : false
21.1234567890123456789012345678901234567890123456789012345678901234+x@example.com : false
22.john..doe@example.com : false
23.john.doe@example..com : false

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

1234567890123456789012345678901234567890123456789012345678901234+x@example.com
john..doe@example.com
john.doe@example..com 
just"not"right@example.com

Ниже приведены критерии для регулярного выражения:

Локальная часть

Локальная часть адреса электронной почты может использовать любой из следующих символов ASCII:

  1. прописные и строчные латинские буквы A to Z и a to z;
  2. цифры 0 to 9;
  3. специальные символы! # $% & '* + - / =? ^ _ `{|} ~
  4. точка ., при условии, что это не первый или последний символ, если только цитируется, и при условии, что он не появляется последовательно если не указано (например, John..Doe@example.com не допускается, но "John..Doe"@example.com разрешено);
  5. space и "(),:;<>@[\] символы допускаются с ограничениями (они разрешены только внутри строки в кавычках, как описано в пункт ниже, и, кроме того, обратная косая черта или двойные кавычки должны быть перед обратной косой чертой); комментарии допускаются в скобках в любом конце локальной части; например john.smith(comment)@example.com и (comment)john.smith@example.com эквивалентны john.smith@example.com.

Домен

  1. прописные и строчные латинские буквы A to Z и a to z;
  2. цифр 0 to 9 при условии, что доменные имена верхнего уровня не являются все-цифровой;
  3. дефис -, при условии, что это не первый или последний символ. Комментарии разрешены как в домене, так и в локальной части; за Например, john.smith@(comment)example.com и john.smith@example.com(comment) эквивалентны john.smith@example.com.

Ответы [ 3 ]

0 голосов
/ 17 ноября 2018

Это не вопрос, который вы задали, но зачем заново изобретать колесо?

У Apache commons есть класс, который охватывает это уже .

org.apache.commons.validator.routines.EmailValidator.getInstance().isValid(email)

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

0 голосов
/ 19 ноября 2018

Вы можете RFC5322 вот так
( референсное правило изменено )

"(?im)^(?=.{1,64}@)(?:(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"@)|((?:[0-9a-z](?:\\.(?!\\.)|[-!#\\$%&'\\*\\+/=\\?\\^`\\{\\}\\|~\\w])*)?[0-9a-z]@))(?=.{1,255}$)(?:(\\[(?:\\d{1,3}\\.){3}\\d{1,3}\\])|((?:(?=.{1,63}\\.)[0-9a-z][-\\w]*[0-9a-z]*\\.)+[a-z0-9][\\-a-z0-9]{0,22}[a-z0-9])|((?=.{1,63}$)[0-9a-z][-\\w]*))$"  

https://regex101.com/r/ObS3QZ/1

 # (?im)^(?=.{1,64}@)(?:("[^"\\]*(?:\\.[^"\\]*)*"@)|((?:[0-9a-z](?:\.(?!\.)|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)?[0-9a-z]@))(?=.{1,255}$)(?:(\[(?:\d{1,3}\.){3}\d{1,3}\])|((?:(?=.{1,63}\.)[0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9])|((?=.{1,63}$)[0-9a-z][-\w]*))$

 # Note - remove all comments '(comments)' before runninig this regex
 # Find  \([^)]*\)  replace with nothing

 (?im)                                     # Case insensitive
 ^                                         # BOS

                                           # Local part
 (?= .{1,64} @ )                           # 64 max chars
 (?:
      (                                         # (1 start), Quoted
           " [^"\\]* 
           (?: \\ . [^"\\]* )*
           "
           @
      )                                         # (1 end)
   |                                          # or, 
      (                                         # (2 start), Non-quoted
           (?:
                [0-9a-z] 
                (?:
                     \.
                     (?! \. )
                  |                                          # or, 
                     [-!#\$%&'\*\+/=\?\^`\{\}\|~\w] 
                )*
           )?
           [0-9a-z] 
           @
      )                                         # (2 end)
 )
                                           # Domain part
 (?= .{1,255} $ )                          # 255 max chars
 (?:
      (                                         # (3 start), IP
           \[
           (?: \d{1,3} \. ){3}
           \d{1,3} \]
      )                                         # (3 end)
   |                                          # or,   
      (                                         # (4 start), Others
           (?:                                       # Labels (63 max chars each)
                (?= .{1,63} \. )
                [0-9a-z] [-\w]* [0-9a-z]* 
                \.
           )+
           [a-z0-9] [\-a-z0-9]{0,22} [a-z0-9] 
      )                                         # (4 end)
   |                                          # or,
      (                                         # (5 start), Localdomain
           (?= .{1,63} $ )
           [0-9a-z] [-\w]* 
      )                                         # (5 end)
 )
 $                                         # EOS

How make sudhansu_@gmail.com this as valid email ID – Mihir Feb 7 at 9:34

Я думаю, спецификация хочет, чтобы локальная часть была заключена в кавычки
или заключена в [0-9a-z].

Но, чтобы обойти позже и сделать sudhansu_@gmail.com действительным, просто
замените группу 2 следующим:

      (                             # (2 start), Non-quoted
           [0-9a-z] 
           (?:
                \.
                (?! \. )
             |                              # or, 
                [-!#\$%&'\*\+/=\?\^`\{\}\|~\w] 
           )*
           @

      )                             # (2 end)

Новое регулярное выражение

"(?im)^(?=.{1,64}@)(?:(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"@)|([0-9a-z](?:\\.(?!\\.)|[-!#\\$%&'\\*\\+/=\\?\\^`\\{\\}\\|~\\w])*@))(?=.{1,255}$)(?:(\\[(?:\\d{1,3}\\.){3}\\d{1,3}\\])|((?:(?=.{1,63}\\.)[0-9a-z][-\\w]*[0-9a-z]*\\.)+[a-z0-9][\\-a-z0-9]{0,22}[a-z0-9])|((?=.{1,63}$)[0-9a-z][-\\w]*))$"

Новая демоверсия

https://regex101.com/r/ObS3QZ/5

0 голосов
/ 16 ноября 2018

Регулярное выражение является наиболее сложным и подверженным ошибкам способом проверки адресов электронной почты.Если вы используете реализацию javax.mail для отправки электронных писем, то самый простой способ определить, будет ли это работать, - использовать предоставленный синтаксический анализатор, потому что, является ли электронное письмо совместимым или нет, если библиотека не может его использовать, то ононе имеет значения.

public static boolean validateEmail(String address) {
    try {
        // if this fails, the mail library can't send emails to this address
        InternetAddress ia = new InternetAddress(address, true);
        return ia.isGroup() && ia.getAddress().charAt(0) != '@';
    }
    catch (Throwable t) {
        return false;
    }
}

Вызов его с помощью false разрешает отправку писем без части @domain при строгом разборе.А так как функция checkAddress, вызываемая внутренне, является закрытой, и мы не можем просто вызвать checkAddress(addr,false,true), так как нам не нужна информация о маршрутизации (функция, практически предназначенная для мошенничества при отскоке сервера), мы должны проверить первую буквупроверенный адрес.

Теперь вы можете заметить, что этот метод проверки на самом деле соответствует RFC 2822, а не 5822. Причина этого в том, что если вы не реализуете свою собственную библиотеку отправителя SMTP, то вы 'Если вы используете тот, который зависит от этого, и если у вас есть адрес, который является 5822-действительным, но 2822-недействительным, то ваша 5822-проверка становится бесполезной.Но если вы реализуете свою собственную библиотеку SMTP 5822, то вам следует учиться на существующих и писать функцию парсера, а не регулярное выражение.

...