Wiki Home

Validate Email Address

Namespace: VFP
There are several levels of validation, and it becomes very complicated for complete validation. Because of Mail Gateways and private system conventions, the only way to completely validate an email is to try to send to it and see if it bounces.

For reference, here are a couple of different, known to be valid, address forms:
A: [email protected]
B: "Person's Name" < [email protected] >
C: [email protected]
D: [email protected]

However, here are the levels at which you can validate:
  1. Format: Make sure there is only one "@", that there is a "." to its right side, that no two symbols ("@", ".", or "#"... any others?) are next to each other, there are no spaces (unless you want to support format "B" in which case you have to get fancier).
    A valid email address does NOT require an "@". I'm running an internal SMTP server here and local mailboxes only require the account name for authentification and delivery, because it can't be anything than the server itself. Demanding an "@" is one of the things that drives me crazy in the Outlook 2003 Junk filter. - Christof Wollenhaupt

    You are not right - accoding to mail related RFCs, email address DOES require @ and domain part - even in case of same-domain transmittion (it can be hovever abbreveated in some cases, but not totally removed). So it will be better for your admin to adhere standards. BTW email address and "account name for authentification" (the one you use in mail clients) ARE different things - second one doesn't requite @ sign. -- Igor Korolyov
  2. Server Existence: Extract the domain name (including tld) and use a lookup to find the MX record associated with that domain, then ping the MX server. Pinging the domain is not good enough because it may not be associated with anything, though it still has a good MX record, and can therefore receive mail. I don't know offhand how to get the MX record, though.
  3. Mailbox Existence: Get the MX record, as above, then connect to the mail server, and use the VRFY command to verify that it will deliver to the provided mailbox.
  4. Delivery: Actually send the message, then wait to see if it gets bounced. Just because the VRFY command says the server CAN deliver to the mailbox doesn't mean that the server WILL deliver that particular message. Spam filters, etc, could cause the delivery to fail.

Examples from RFC821 of validating a mailbox:
                Example of Verifying a User Name
            S: VRFY Smith
            R: 250 Fred Smith 
            S: VRFY Smith
            R: 251 User not local; will forward to 
            S: VRFY Jones
            R: 550 String does not match anything.
            S: VRFY Jones
            R: 551 User not local; please try <[email protected]>
S: VRFY Gourzenkyinplatz
R: 553 User ambiguous.

The best way I've found is to use regular expressions.

You can also use winsock to check the Domain exists (I'm still trying to work out how to do the MX lookup).

Here's what I got so far.

p.s. I don't want to steal anyones glory. The actual Regular Expression was 'blagged' from Andy Smith (see

The winsock stuff I use is from this very site!. [search for pingstate( pingx( pcWebSite ,80 ) )]
* Validate email structure
* thisform.regexp.pattern = "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"
LPARAMETERS pcEmail as String
pcEmail = ALLTRIM(pcEmail)
RETURN  IIF(thisform.regexp.execute(pcEmail,.f.) > 0,.T.,.F.)

Thanks every-one
p.s. I'm sure Jmail.dll comes with a structure validation method
[email protected]

I would change the sample to the following, easy to test using WSH's Reg Exp object:
LPARAMETERS pcEmail as String
pcEmail = ALLTRIM(pcEmail)

Local oRE
oRE = CreateObject("VBScript.RegExp")
oRE.Pattern = "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"

llresult = oRE.test(pcEmail)
-- Alex Feldstein
The sample regex patterns above disallow the use of plus-sign, ampersand, exclamation-point,
dollar-sign, and others implicitly allowed by RFC 822 (any printable ASCII char NOT listed
under "specials" on pg 45 of that document is allowed), to the left of the at-sign. I
particularly care about plus-sign, as I normally choose to use the addresses described as
"type D" at the top of this page.

It feels good being able to leave this comment; thanks for having this be a wiki. -- James Merrill

If you replace the above regex pattern with this one Craig Boyd blogged about here,guid,91241006-595a-487d-ac06-d0fc1fc71632.aspx,
the "Type D" address will be validated okay.

oRE.Pattern = "^([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$"

-- David Fung

The expression given by David Fung is almost right but it will prevent single character usernames, eg [email protected] This is rare, but I'm pretty sure it's a legal email address. It also won't allow a dot _and_ and an equals eg abc.def=[email protected] A slightly more accurate one might be:

oRE.Pattern = "^([0-9a-zA-Z]+([-.=_+&])*[0-9a-zA-Z]+)*@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$"

(ie allowing the symbol followed by letters one or more times) but I don't use foxpro so I can't test this actually works.

-- GavinMc

I tested the above in VFP 8 using "[email protected]" and it works. (Note that it is dash, underscore, dash.)
The Fung version returned false in this case.
Thanks, Gavin!

-- Ray Kirk

While the underscores and dashes for the above string may work, I don't see the single character username working as it stands.

GavinMc's string: "^([0-9a-zA-Z]+([-.=_+&])*[0-9a-zA-Z]+)*@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$"
Single Character Username No username at all
E-Mail Addr "[email protected]" ""
Result No Good ! Just Fine!

Obviously, that is not desired behavior.

Apparently Comprehensive Perl + Reg Exp code:
The RFC that describes this:
Also see the NET4COM Regular Expression with the Sedna October CTP
-- Rhodri C Evans
Contributors: wgcs Alex Feldstein
Category Automation Category Code Samples
( Topic last updated: 2015.08.31 11:17:52 AM )