Validating Email Adress.

Does anybody have Natural Code to validate that an email address is a valid email address

1 Like

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: Id 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 :slight_smile:
Of course, this is just “my 2 cents”:slight_smile:

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 :slight_smile:
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” ?