Postgres功能验证电子邮件地址

时间:2011-02-05 17:02:24

标签: postgresql

一个检查约束会调用一个函数来验证电子邮件地址对我不起作用。

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。我尝试了其他几个正则表达式但是徒劳无功。任何人都可以指出这个功能有什么问题吗?

Screenshot

6 个答案:

答案 0 :(得分:13)

这些答案中有很多是以正确的方式关闭。这些是我提交的要点。

  • 您想使用域名 - 不是规则系统。
  • 不想使用正则表达式验证这些电子邮件地址。(2017年3月更新:不再适用)

我展示two methods of how to do this the right on 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);

有关详细信息,我高度建议您read the answer in full。在答案中,我还会向您展示如何创建DOMAIN而不是Email::Valid ,并解释为什么我不再使用该方法。

答案 1 :(得分:9)

在你付出很多努力之前,你要做的就是确保你没有踢出有效的电子邮件地址。可以或不能在电子邮件地址中存在各种疯狂规则,如果您错误地指出错误的方向,那么具有完全有效电子邮件地址的用户可能会被您的系统拒绝。

确定电子邮件地址是否有效的最佳方法是将其用作需要电子邮件的注册过程的一部分。其他任何事情都是很多工作,收获甚微。

答案 2 :(得分:3)

我推荐使用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

答案 3 :(得分:2)

如果你能找到一个与你满意的电子邮件地址匹配的正则表达式,请考虑它是否可能不是更有用的域而不是检查约束。

对于一些陷阱,请参阅regular-expressions.info

答案 4 :(得分:1)

不要尝试创建正则表达式来验证电子邮件!

众所周知,很难完成。这是一个更好的解决方案:

假设您在数据库主机上安装了Perl,请使用CPAN在同一主机上安装Email :: Valid模块:

you@localhost$ cpan Email::Valid

然后确保安装了PL / Perl。在psql中连接到您的数据库并添加plperlu作为语言:

CREATE EXTENSION plperlu;

(请记住,这是一种不受信任的语言,因此您将提供您的数据库直接文件访问权限,如果有人要将恶意代码插入您的Perl模块或数据库函数中,这可能会带来安全风险但是,您需要在下一步中执行此操作。)

将以下功能添加到您的数据库中:

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;

为您的列上的表添加触发器约束(假设您的表名为"用户"并且您的列名为" 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感到不舒服,您可以将相关功能移植到数据库中。

答案 5 :(得分:0)

适合我:

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=>