9

Since Delphi does not have any regular expressions library built-in, have you seen a good function to validate email addresses at least to some degree in using only Delphi RTL/VCL?

I don't want to link additional *.dll to my product integrating regular expression support and I need also Delphi 7 compatibility. Embedding regex library into exe increases it's size and I doubt it worths adding next 100k because you just need 10-50-lines function of email validation.

mjn
  • 36,362
  • 28
  • 176
  • 378
Vladislav Rastrusny
  • 29,378
  • 23
  • 95
  • 156
  • 7
    http://www.howtodothings.com/computers/a1169-validating-email-addresses-in-delphi.html – Marko Aug 25 '10 at 12:20
  • 1
    For what it's worth, the next version of Delphi will have a regex library built into the RTL, and it's due out in just a few more days... – Mason Wheeler Aug 25 '10 at 12:44
  • Validating email addresses is one of the good examples of where using regular expressions might not be a smart idea - http://stackoverflow.com/questions/36261/test-expand-my-email-regex/36277#36277 – mjn Aug 25 '10 at 12:46
  • 1
    @Marko: this link should be an answer, not a comment – mjn Aug 25 '10 at 13:06
  • Agree. Make it an answer, please. I will accept it. – Vladislav Rastrusny Aug 25 '10 at 13:44
  • Why does Delphi's lack of a built-in regex library necessarily lead to the need to validate an e-mail address using only the RTL? – Rob Kennedy Aug 25 '10 at 16:04
  • Primarily because I don't want to link my project with some huge links only to have email validation 0.01% more correct. What do you suggest? – Vladislav Rastrusny Aug 25 '10 at 19:25
  • @Mason: 399 USD (at cheapest) is a pretty expensive regex library ;). And yes, I know the purchaser gets more than just that, but given that they are coming from a Delphi 7 position, they will also likely be entering a world of Unicode pain too. Much easier and more helpful to provide a link to one of the existing, free regex components for Delphi imho (someone already did, so no need for me to repeat that particular exercise). – Deltics Aug 25 '10 at 20:56
  • 1
    Delphi hasn't done "huge links" since the days when it was still called Turbo Pascal, and even then it was the very early days. Delphi has "smart linking," so it doesn't link code that it knows you didn't use. I suggest you use whatever libraries you want that solve your problem and don't hurt you with burdensome licenses, although the same advice applies to non-library code like what Marko linked to. (Please remember to use "@" in front of people's names in comments so Stack Overflow will notify them that you've responded to them. Then it won't take 12 hours to get a response from them.) – Rob Kennedy Aug 26 '10 at 08:07
  • @Rob Kennedy: the source I am using validation function in is used by another programmers who don't like to take 55 external components together with the project. – Vladislav Rastrusny Aug 26 '10 at 09:09

3 Answers3

5

The big problem on email address validation is that RFC 822 is so broad, that no regular expression will help.

The article I Knew How To Validate An Email Address Until I Read The RFC describes this well.
It quotes the RFC the local-part MUST be interpreted and assigned semantics only by the host specified in the domain part of the address (the local part is the part before the @ sign in an email address).

So:
the only way to check if an email address is valid, is to setup an SMTP connection to the host accepting mail for that particular domain, and start up the email handshaking process with the email address you are trying to verify.

This is what a lot of anti-SPAM software does to verify sender email addresses: they contact the SMTP server of the sender of the email, try to setup an SMTP handshake, and if that goes OK, they rate the incoming email as more like to not be SPAM.

You can use the Indy SMTP client component to send mail; the accepted answer to this question explains how.

--jeroen

Community
  • 1
  • 1
Jeroen Wiert Pluimers
  • 23,965
  • 9
  • 74
  • 154
  • 1
    Personally I would only enforce: 1. Have only one @ char in the string (with index > 0) 2. Have no characters in range [0..32] in the string. 3. Have at least one "." character after the @'s index (with a distance of 1 or more). 4. No : or / or \ characters in the domain name. – alex Aug 25 '10 at 14:43
  • 4
    RFC 822 had been obsoleted by 2822 which removed some syntax allowed by 822. Anyway one rarely needs the full 2822 syntax - allowing for a much simpler regex –  Aug 25 '10 at 14:52
  • 4
    you do not need to do an SMTP email handshake just to validate an address. Yes, you have to connect to the email domain's SMTP server, but after that you can use the SMTP `VRFY` command to ask the server if the address is valid. Indy's TIdSMTP component has a Verify() method for that. – Remy Lebeau Oct 27 '10 at 18:06
  • 1
    @Remy: I totally forgot about the VRFY, but now that you mention it, I do remember that not all SMTP servers support it. But it has been a long time since I came across one that didn't support it. So thanks for mentioning VRFY. – Jeroen Wiert Pluimers Oct 27 '10 at 20:45
4

As requested I'm making my comment an answer..

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

Thanks!

Marko
  • 71,361
  • 28
  • 124
  • 158
0

For the old version of Delphi that doesn't have Regular expression :

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;

For the one who like to use RegExpression using Database server

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;
ffert2907
  • 370
  • 4
  • 16