Функция Postgres для проверки адреса электронной почты - PullRequest
8 голосов
/ 05 февраля 2011

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

CREATE OR REPLACE FUNCTION f_IsValidEmail(text) returns BOOLEAN AS 
'select $1 ~ ''^[^@\s]+@[^@\s]+(\.[^@\s]+)+$'' as result
' LANGUAGE sql;



SELECT f_IsValidEmail('myemail@address.com');

Функция возвращает false, что должно быть true. Я пробовал пару других регулярных выражений, но тщетно. Кто-нибудь может указать, что не так с этой функцией?

Скриншот

Ответы [ 6 ]

13 голосов
/ 26 марта 2014

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

  • Вы хотите использовать домен - НЕ система правил.
  • Вы НЕ хотитеподтвердите эти адреса электронной почты с помощью регулярного выражения. (Обновление марта 2017 г .: больше не соответствует действительности)

Я показываю два способа сделать это правильно на DBA.StackExchange.com.Как для проверки MX-записи, так и с использованием спецификации HTML5.Вот краткое и приятное.

CREATE EXTENSION citext;
CREATE DOMAIN email AS citext
  CHECK ( value ~ '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$' );

SELECT 'foobar@bar.com'::email;
SELECT CAST('foobar@bar.com' AS email);

Для получения дополнительной информации я весьма предлагаю вам прочитать ответ полностью .В ответе я также покажу, как создать DOMAIN сверх Email::Valid, и объясню, почему я больше не использую этот метод.

9 голосов
/ 06 февраля 2011

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

Лучший способ определить, является ли адрес электронной почты действительным, состоит в том, чтобы использовать его как часть процесса регистрации, когда электронная почта ТРЕБУЕТСЯ.Все остальное - много работы за небольшую выгоду.

3 голосов
/ 06 февраля 2011

Я рекомендую решение с использованием PL / Perl и модуля Email :: Address. Примерно так:

CREATE OR REPLACE FUNCTION email_valid(email text) RETURNS bool
LANGUAGE plperlu
AS $$
use Email::Address;
my @addresses = Email::Address->parse($_[0]);
return scalar(@addresses) > 0 ? 1 : 0;
$$;

См. Также http://wiki.postgresql.org/wiki/Email_address_parsing.

2 голосов
/ 06 февраля 2011

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

О некоторых подводных камнях см. регулярные выражения.info .

1 голос
/ 12 марта 2014

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

Общеизвестно, что это трудно сделать.Вот лучшее решение:

Предполагая, что на вашем хосте базы данных установлен Perl, установите модуль Email :: Valid на том же хосте с использованием CPAN:

you@localhost$ cpan Email::Valid

Затем убедитесь, что выустановить PL / PerlПодключитесь к вашей базе данных в psql и добавьте plperlu в качестве языка:

CREATE EXTENSION plperlu;

(Имейте в виду, что это ненадежный язык, поэтому вы будете предоставлять прямой доступ к файлу вашей БД, что может создать безопасностьриск того, что кто-то вставит вредоносный код в ваши модули Perl или в функции db. Однако вам нужно сделать это для следующего шага.)

Добавьте следующую функцию в вашу базу данных:

CREATE FUNCTION validate_email() RETURNS trigger AS $$
  use Email::Valid;
  return if Email::Valid->address($_TD->{new}{email});
  elog(ERROR, "invalid email address $_TD->{new}{email} inserted into $_TD->{table_name}(email)");
  return "SKIP";
$$ LANGUAGE plperlu;

Добавьте ограничение триггера к вашей таблице в вашем столбце (при условии, что ваша таблица называется «users», а ваш столбец - «email»):

CREATE TRIGGER users_valid_email_trig
  BEFORE INSERT OR UPDATE ON users
  FOR EACH ROW EXECUTE PROCEDURE validate_email();

И все готово!

Это решение использует модуль Email :: Valid Perl для обработки проверки, которая, в свою очередь, опирается на регулярное выражение для обеспечения соответствия RFC 822.Тем не менее, это монстр регулярных выражений, поэтому не пытайтесь придумать свой собственный.

Если вам неудобно включать plperlu вместо простого plperl, вы, вероятно, могли бы перенести соответствующие функции в вашу базу данных..

0 голосов
/ 05 февраля 2011

у меня работает:

psql (9.0.2)
Type "help" for help.

postgres=> CREATE OR REPLACE FUNCTION "f_IsValidEmail"(text) returns BOOLEAN AS
postgres-> 'select $1 ~ ''^[^@\s]+@[^@\s]+(\.[^@\s]+)+$'' as result
postgres'> ' LANGUAGE sql;
CREATE FUNCTION
postgres=> commit;
COMMIT
postgres=> SELECT "f_IsValidEmail"('myemail@address.com');
 f_IsValidEmail
----------------
 t
(1 row)

postgres=>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...