Does anybody have Natural Code to validate that an email address is a valid email address
To keep things simple: The only thing I would check is, if there is a @-character entered and at least one character before and afterwards. The character after the @ must be alphanumerical (due to DNS-Standards).
if #email = mask (P*'@'A)
write 'valid'
else
write 'invalid'
end-if
Attached is a routine that does fairly detailed checking.
E-AddressCheck.zip (4.59 KB)
That’s really detailed :shock:
But to be honest: I don’t want to keep the TLDs up to date…
This is probably overkill in most situations, but met our needs for global processing
* Function: Validate email address
* NOTE: While there are many additional exceptions to email
* addresses in the wild, we do not expect such deviations
* to be given to us for simple contact information
* See also: http://en.wikipedia.org/wiki/E-mail_address
************************************************************************
* PARAMETERS:
* Input: #email - the actual value being evaluated
* (Consists of LOCALNAME@HOSTNAME)
*
* Output: #valid - Did #email pass the validation? (TRUE or FALSE)
* #msg - Text description with details to support #valid
************************************************************************
* Syntax: if screen-input.#email ne ' ' /* If email is not required
* reset gsdexema
* gsdexema.#email := screen-input.#email
* callnat 'gsdexmn1'
* gsdexma1
* if not gsdexma1.#valid /* Optional: You can perform any
* reinput gsdexma1.#msg /* action instead of using #msg
* end-if
* end-if
************************************************************************
* Revision History
* Date Programmer Description
* 03-Aug-2009 George Dinsmore Initial creation - GeorgeDinsmore.com
************************************************************************
define data
parameter using rrs998a1
local
1 #work-fields
2 #email-len (n2) /* Length of #email
2 #host-len (n2) /* Length of #host-name
2 #hostname (a65) /* Part of an email address after the @
2 redefine #hostname
3 #host-array (a1/65)
2 #host-pos (n2) /* Used to determin length of #host-name
2 #index (n2) /* Index for #email-array
2 #index2 (n2) /* Index for array comparison
2 #local-len (n2) /* Length of #local-name
2 #localname (a65) /* Part of an email address before the @
2 redefine #localname
3 #local-array (a1/65)
2 #local-pos (n2) /* Used to determin length of #local-name
2 #pos (n2) /* Position of '@' in email address
2 #qty-at-sign (n2) /* # of at-signs in the email address
2 #qty-quotes (n2) /* # of quotes in the email address
2 #quotes (l) /* Is local name embedded in quotes?
2 #valid-format (l) /* Does a '.' follow the '@'?
end-define
************************************************************************
reset #work-fields
#valid := false
*
/* 1. Did we receive any value to validate?
#msg := 'EMAIL ADDRESS cannot be blank'
escape routine
end-if /* (0560)
*
/* 2. Email address begins with at-sign
if #email-array(1) = '@'
#msg := 'EMAIL ADDRESS cannot begin with "@"'
escape routine
end-if /* (0620)
************************************************************************
* Initializations
************************************************************************
/* Get length of #email-array
examine #email for ' ' giving length #email-len
*
/* Determine how many at-signs are present
examine #email for '@' giving #qty-at-sign
*
/* Determine how many quotes are present
examine #email for H'22' giving #qty-quotes /* H'22' = "
************************************************************************
* General email address validations
************************************************************************
decide for first condition
when #qty-quotes = 0 and
#qty-at-sign = 1
* /* Get position of the at-sign to separate localname and hostname
examine #email for '@' giving position #pos
*
/* 3. Require one at-sign when no quotes
when #qty-quotes = 0 and
#qty-at-sign ne 1
#msg := 'EMAIL ADDRESS must contain one "@"'
escape routine
*
/* 4. Allow only one at-sign when no quotes
when #qty-quotes = 0 and
#qty-at-sign gt 1
#msg := 'EMAIL ADDRESS can contain only one "@"'
escape routine
*
/* 5. If quotes are present, they can only be the first AND last
/* characters of #localname
when #qty-quotes = 2 and
#email-array(1) = H'22'
examine #email for h'2240' giving position #pos /* H'2240' = "@
if #pos > 0
#quotes := true
else
#msg := 'EMAIL ADDRESS quotation marks not used properly'
escape routine
end-if
*
/* 6. If quotes are present, there can only be two
when #qty-quotes ne 2
#msg := 'EMAIL ADDRESS quotation marks not used properly'
escape routine
*
when none
ignore
end-decide /* (1780)
*
/* 7. Are there consecutive "dots"?
for #index 1 to #email-len
#index2 := #index + 1
if #email-array(#index) = '.' and
#email-array(#index2) = '.'
compress '"' #email-array(#index) #email-array(#index2) '"'
into #msg leaving no
compress
'EMAIL ADDRESS cannot contain consecutive dots:'
#msg into #msg
escape routine
end-if /* (1220)
end-for /* (1200)
************************************************************************
* Extract localname and hostname from email address
************************************************************************
/* Extract localname from email address and find its length
#local-pos := #pos
if not #quotes
subtract 1 from #local-pos /* Skip at-sign
end-if
move substr(#email,1,#local-pos) to #localname
examine #localname for ' ' giving length #local-len
*
/* Extract hostname from email address and find its length
#host-pos := #pos + 1 /* Skip at-sign
if #quotes
add 1 to #host-pos /* Account for quote position
end-if
**write *program *line #host-pos #email-len / #email
if #host-pos + #email-len > 65
#msg := 'EMAIL ADDRESS is invalid'
escape routine
end-if
move substr(#email,#host-pos,#email-len) to #hostname
examine #hostname for ' ' giving length #host-len
************************************************************************
* Evaluate localname portion of email address
************************************************************************
if not #quotes
/* 8. Is the first character a dot?
if #local-array(1) = '.'
compress '"' #local-array(1) '"' into #msg leaving no
compress 'EMAIL ADDRESS local name cannot start with:'
#msg into #msg
escape routine
end-if
*
/* 9. Is the last character a dot?
if #local-array(#local-len) = '.'
compress '"' #local-array(#local-len) '"' into #msg leaving no
compress 'EMAIL ADDRESS local name cannot start with:'
#msg into #msg
escape routine
end-if
*
for #index 1 to #local-len
/* 10. Are there spaces in the localname?
if #local-array(#index) = ' '
#msg := 'EMAIL ADDRESS local name cannot contain spaces'
escape routine
end-if /* (1770)
*
/* 11. Are there special characters in the localname?
if #local-array(#index) = mask(s) and
not(#local-array(#index) = '!' or = '#' or = '$' or = '%' or
= '&' or = '*' or = '+' or = '-' or = '/' or = '=' or = '?' or
= '^' or = '_' or = '`' or = '{' or = '}' or = '~' or = '.')
compress '"' #local-array(#index) '"' into #msg leaving no
compress 'EMAIL ADDRESS local name cannot contain:'
#msg into #msg
escape routine
end-if /* (1830)
end-for /* (1750)
end-if /* (1580)
************************************************************************
* Evaluate hostname portion of email address
************************************************************************
/* 12. Does hostname contain special characters besides a hyphen
for #index 1 to #host-len /* Start with 2 to skip "@"
if #host-array(#index) = mask(s) and
not (#host-array(#index) = '-' or = '.')
compress '"' #host-array(#index) '"' into #msg leaving no
compress 'EMAIL ADDRESS host cannot contain special character:'
#msg into #msg
escape routine
end-if /* (1990)
*
/* 13. Are there spaces in the hostname?
if #host-array(#index) = ' '
#msg := 'EMAIL ADDRESS host name cannot contain spaces'
escape routine
end-if /* (2080)
*
/* 14. Is there at least one "dot" (.) in the host-name?
if #host-array(#index) = '.'
#valid-format := true
end-if /* (2140)
end-for /* (1980)
if not #valid-format
#msg := 'EMAIL ADDRESS must include a "." after the "@"'
escape routine
end-if /* (2180)
*
/* 15. Does the hostname begin with a special character?
if #host-array(1) = mask(s)
compress '"' #host-array(1) '"' into #msg leaving no
compress 'EMAIL ADDRESS host cannot begin with:'
#msg into #msg
escape routine
end-if /* (2240)
*
/* 16. Does the hostname end with a special character?
if #host-array(#host-len) = mask(s)
compress '"' #host-array(#host-len) '"' into #msg leaving no
compress 'EMAIL ADDRESS host cannot end with:'
#msg into #msg
escape routine
end-if /* (2320)
*
#valid := true /* Passed all edits
end
Hi geoscodin,
Well, this is certainly impressive routine which would (Im pretty sure) do the JOB. Just my 2 cents to your function if I may recommend anything of course: I
d replace all of those (N2) with (I4), since the “rule of thumb” (in my opinion) would be as follows:
var (Nxx) is for Display/Write; to count anything in INTEGER or use as index (like in your FUNCTION) var (I4) would be ALWAYS better (and even slightly faster :-); well, the speed is negligible, but I think it`s rather a matter of principle
Of course, this is just “my 2 cents”
Best regards,
Nikolay
Depending on your environment; have you considered shipping e-mail addresses to an internet server and see if you get an error return?
Of course, this would not work if you are solely concerned with valid format, rather than valid website.
steve
It is a pity (another option) that NATURAL does NOT support such a powerful feature as regular expression
I remember it was a REAL piece of cake to validate e-mail address in Java using its regex package :-), I mean
java.util.regex
Perhaps, there`s an easy way to call from Natural (depending on your environment, as Steve fairly mentioned) “something with such a support” ?