Проверка формата электронной почты RFC 5322
Как я могу проверить, являются ли электронные письма, сгенерированные моим кодом, действительными в соответствии с RFC 5322?
3 ответа
Вот регулярное выражение PCRE (взятое из библиотеки PHP), которое будет проверяться в соответствии с RFC 5322:
'/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z\d-]{64,})(?1)(?>([a-z\d](?>[a-z\d-]*[a-z\d])?)(?>(?1)\.(?!(?1)[a-z\d-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f\d]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f\d][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f\d]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(?>\.(?9)){3}))\])(?1)$/isD'
В отличие от ответа Питера, он допускает однокомпонентные доменные имена (которые являются синтаксически действительными) и литералы адресов IPv6.
Тем не менее, я настоятельно рекомендую вместо этого проверить в соответствии с RFC 5321, который не допускает комментариев или складывания пробелов (которые семантически невидимы и поэтому фактически не являются частью адреса электронной почты) или для устаревших локальных частей (которые могут просто быть переписан как не устаревшие строки в кавычках):
'/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!"?(?>\\\[ -~]|[^"]){65,}"?@)(?>([!#-\'*+\/-9=?^-~-]+)(?>\.(?1))*|"(?>[ !#-\[\]-~]|\\\[ -~])*")@(?!.*[^.]{64,})(?>([a-z\d](?>[a-z\d-]*[a-z\d])?)(?>\.(?2)){0,126}|\[(?:(?>IPv6:(?>([a-f\d]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f\d][:\]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?))|(?>(?>IPv6:(?>(?3)(?>:(?3)){5}:|(?!(?:.*[a-f\d]:){6,})(?5)?::(?>((?3)(?>:(?3)){0,4}):)?))?(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(?>\.(?6)){3}))\])$/iD'
Регулярное выражение электронной почты в соответствии с политикой RFC 5322 После стольких усилий я сделал регулярное выражение, проверяющее все случаи в соответствии с 5322, кроме одного: (1) admin@mailserver1 (локальное доменное имя без TLD, хотя ICANN настоятельно не рекомендует использовать адреса электронной почты без точек)
^ (? =.{1,64}@) ((?: [A-Za-z0-9!#$%&'*+ - / =?^ {|}~ (),:;<>@[ ].]) +") (?:. (?: [A-Za-z0-9!#$%&'*+ - / =?^
\{\|\}~]+|"(?:\\"|\\\\|[A-Za-z0-9\.!#\$%&'\*\+\-/=\?\^_
{|}~ (),:;<>@[].]) +")) ) @ (? =.{1,255}.) ((?: [A-Za-z0-9]+ (? :( ?: [A-Za-z0-9-][A-Za-z0-9])?).)+[A-Za-z]{2,})| (((0 |[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6} (0 |)])$
Нажмите здесь, чтобы получить четкое представление об этом регулярном выражении https://regex101.com/r/7u0dze/1
Использование этого регулярного выражения на 98% действительно. Это не подтверждает следующее:
postbox@com
admin@mailserver1
user@[IPv6:2001:db8:1ff::a0b:dbd0]
Но это охватывает все остальное
^(([^<>()[\\]\\.,;:\\s@\"]+(\\.[^<>()[\\]\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$
Примечание. Это переносится непосредственно из некоторого производственного кода Golang, поэтому добавляются косые черты.