Delphi: validate email without regular expressions
Asked Answered
O

3

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.

Opah answered 25/8, 2010 at 12:16 Comment(10)
howtodothings.com/computers/…Steeple
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...Georgianngeorgianna
Validating email addresses is one of the good examples of where using regular expressions might not be a smart idea - stackoverflow.com/questions/36261/test-expand-my-email-regex/…Zinazinah
@Marko: this link should be an answer, not a commentZinazinah
Agree. Make it an answer, please. I will accept it.Opah
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?Myongmyopia
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?Opah
@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).Horrocks
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.)Myongmyopia
@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.Opah
S
4

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

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

Thanks!

Steeple answered 25/8, 2010 at 20:47 Comment(7)
Note that that code implements an obsolete spec. It was even obsolete at the time the code was first published.Myongmyopia
@Rob Kennedy: Do you mean CharInSet warning?Opah
No, I mean that the code implements RFC 822. The code was published in May 2001. RFC 2822 was published in April 2001.Myongmyopia
@Rob Kennedy: Ah, I see, thanks. But that would be probably enough for me anyway. 2822 is more strict as I know.Opah
Been through this recently, resorted to port the Apache Commons validators, which seem to be widely accepted as "good enough" - github.com/leus/delphi-emailvalidatorEmbus
This function will fail if the domain begins with a number, which is a valid email. For instance : [email protected]Zibeline
This is a great example of why link-only answers are very bad. Now, only a decade later, the link is dead and this answer is completely useless.Scibert
L
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

Lew answered 25/8, 2010 at 13:57 Comment(4)
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.Darbydarce
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 regexProtect
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.Oxymoron
@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.Lew
S
4

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

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

Thanks!

Steeple answered 25/8, 2010 at 20:47 Comment(7)
Note that that code implements an obsolete spec. It was even obsolete at the time the code was first published.Myongmyopia
@Rob Kennedy: Do you mean CharInSet warning?Opah
No, I mean that the code implements RFC 822. The code was published in May 2001. RFC 2822 was published in April 2001.Myongmyopia
@Rob Kennedy: Ah, I see, thanks. But that would be probably enough for me anyway. 2822 is more strict as I know.Opah
Been through this recently, resorted to port the Apache Commons validators, which seem to be widely accepted as "good enough" - github.com/leus/delphi-emailvalidatorEmbus
This function will fail if the domain begins with a number, which is a valid email. For instance : [email protected]Zibeline
This is a great example of why link-only answers are very bad. Now, only a decade later, the link is dead and this answer is completely useless.Scibert
S
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;
Stressful answered 11/2, 2016 at 9:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.