【问题标题】:Delphi: validate email without regular expressionsDelphi:验证没有正则表达式的电子邮件
【发布时间】:2010-08-25 12:16:37
【问题描述】:

由于 Delphi 没有内置任何正则表达式库,您是否看到过一个很好的功能,可以在仅使用 Delphi RTL/VCL 时至少在某种程度上验证电子邮件地址?

我不想将其他 *.dll 链接到我的集成正则表达式支持的产品,我还需要 Delphi 7 兼容性。将正则表达式库嵌入 exe 会增加它的大小,我怀疑是否值得添加下一个 100k,因为您只需要 10-50 行电子邮件验证功能。

【问题讨论】:

  • 不管怎样,Delphi 的下一个版本将在 RTL 中内置一个正则表达式库,而且几天后就会发布......
  • 验证电子邮件地址是一个很好的例子,说明使用正则表达式可能不是一个聪明的主意 - stackoverflow.com/questions/36261/test-expand-my-email-regex/…
  • @Marko:这个链接应该是答案,而不是评论
  • Delphi 自从它仍然被称为 Turbo Pascal 的日子以来就没有做过“巨大的链接”,即使那时它还是很早的日子。 Delphi 具有“智能链接”,因此它不会链接它知道您没有使用的代码。我建议你使用任何你想要的库来解决你的问题并且不要用繁重的许可证伤害你,尽管同样的建议适用于非库代码,比如 Marko 链接的代码。 (请记住在 cmets 中的人员姓名前使用“@”,以便 Stack Overflow 通知他们您已回复他们。然后不会需要 12 小时才能得到他们的回复。)

标签: delphi validation email delphi-2010 delphi-7


【解决方案1】:

根据要求,我将我的评论作为答案..

http://www.howtodothings.com/computers/a1169-validating-email-addresses-in-delphi.html

谢谢!

【讨论】:

  • 请注意,该代码实现了一个过时的规范。在代码首次发布时,它甚至已经过时了。
  • @Rob Kennedy:你的意思是 CharInSet 警告吗?
  • 不,我的意思是代码实现了 RFC 822。代码发布于 2001 年 5 月。RFC 2822 发布于 2001 年 4 月。
  • 最近经历了这个,求助于移植 Apache Commons 验证器,这似乎被广泛接受为“足够好” - github.com/leus/delphi-emailvalidator
  • 如果域以数字开头,则此功能将失败,该数字是有效的电子邮件。例如:me@1domain.com
【解决方案2】:

电子邮件地址验证的最大问题是RFC 822 太宽泛了,没有任何正则表达式会有所帮助。

文章I Knew How To Validate An Email Address Until I Read The RFC很好地描述了这一点。
它引用了 RFC the local-part MUST be interpreted and assigned semantics only by the host specified in the domain part of the addresslocal part 是电子邮件地址中@ 之前的部分)。

所以:
检查电子邮件地址是否有效的唯一方法是设置与接收该特定域邮件的主机的 SMTP 连接,并使用您尝试验证的电子邮件地址启动电子邮件握手过程。

这就是很多反垃圾邮件软件用来验证发件人电子邮件地址的方式:他们联系电子邮件发件人的 SMTP 服务器,尝试设置 SMTP 握手,如果一切正常,他们会对收到的电子邮件进行评分更像不是垃圾邮件。

您可以使用 Indy SMTP 客户端组件发送邮件; this question 接受的答案解释了如何。

--杰罗恩

【讨论】:

  • 就我个人而言,我只会强制执行:1. 字符串中只有一个 @ char(索引 > 0) 2. 字符串中没有 [0..32] 范围内的字符。 3. 至少有一个“.” @ 的索引后的字符(距离为 1 或更大)。 4.域名中没有:或/或\字符。
  • RFC 822 已被 2822 淘汰,它删除了 822 允许的一些语法。无论如何,很少需要完整的 2822 语法 - 允许更简单的正则表达式
  • 您不需要为了验证地址而进行 SMTP 电子邮件握手。是的,您必须连接到电子邮件域的 SMTP 服务器,但之后您可以使用 SMTP VRFY 命令询问服务器地址是否有效。 Indy 的 TIdSMTP 组件为此提供了一个 Verify() 方法。
  • @Remy:我完全忘记了 VRFY,但现在你提到它,我确实记得并非所有 SMTP 服务器都支持它。但是很久没有遇到不支持的了。所以感谢您提到 VRFY。
【解决方案3】:

对于没有正则表达式的旧版Delphi:

function TForm1.IsValidEmail(email: string): boolean;
const
  charslist = ['_', '-', '.', '0'..'9', 'A'..'Z', 'a'..'z'];
var
  Arobasc, lastpoint : boolean;
  i, n : integer;
  c : char;
begin
  n := Length(email);
  i := 1;
  Arobasc := false;
  lastpoint := false;
  result := true;
  while (i <= n) do begin
    c := email[i];
    if c = '@' then
    begin
      if Arobasc then  // Only 1 Arobasc
      begin
        result := false;
        exit;
      end;
      Arobasc := true;
    end
    else if (c = '.') and Arobasc then  // at least 1 . after arobasc
    begin
      lastpoint := true;
    end
    else if not(c in charslist) then  // valid chars
    begin
      result := false;
      exit;
    end;
    inc(i);
  end;
  if not(lastpoint) or (email[n] = '.')then  // not finish by . and have a . after arobasc
    result := false;
end;

对于喜欢使用数据库服务器使用 RegExpression 的人

function TForm1.IsValidEmail(const AMail: string): Boolean;
var
  lQry: TSQLQuery;
begin
  // no REGEXP in Delphi 2009 -> use of REGEPX Oracle
  lQry := TSQLQuery.Create();
  lQry.SQLConnection := SQLConnection1;
  try
    vQry.SQL.Text := 'SELECT REGEXP_SUBSTR( ' + QuotedStr(aMail) + ', ''^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{1,}$'' ) "EMAIL" FROM DUAL';  // ORACLE
    // vQry.SQL.Text := 'SELECT ' + QuotedStr(aMail) + ' REGEXP ''^[a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9.-]@[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]\.[a-zA-Z]{2,4}$'';  // MySQL
    lQry.Open;
    Result := not lQry.Eof and ( lQry.FieldByName( 'EMAIL' ).AsString = AMail );
  finally
    FreeAndNil(lQry);
  end;
end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    相关资源
    最近更新 更多