Example RPG Email Validation program – SQLRPGLE ILE 

 October 21, 2020

By  NickLitten

Let’s look at a quick little example RPG email validation program – SQLRPGLE ILE

There are lots of code snippets, example programs, and long waffling discussions in internet land filled with pointy-headed AS400, Series, and IBM i programmer chaps (and chappettes) arguing about the best way to “validate an email address in RPG”.

I know because I’ve read nearly all of them, as well as tried all the techniques.

But yesterday I stumbled across a really simple variation of an established technique that seems to work 99% of the time (note: there is no perfect validation expressions since email address rules are changing frequently)

Using Regex to validate an email

Look at this SQLRPGLE code snippet:

exec sql
    set :myCount = regexp_count( :myEmail, '^(?:\w+\.?)*\w+@(?:\w+\.)*\w+$');

If myCount = 1;
   // email is good 
   // email is malformed 

Pretty simple huh!

So , what are we doing with this regular expression?

The regular expression ‘^(?:\w+\.?)*\w+@(?:\w+\.)*\w+$‘ is saying – check this input string meets the standard of something before an @ sign followed by something dot something:

Example RPG

The internet is filled with alternate regular expressions to make the email validation logic as complex as you wish.

For my purposes this simple logic is exactly what I need.

So, let’s plumb this into an example RPG program, wrapped in a tidy sub-procedure, with a sprinkling of comments, my favorite QUILNGTX *API for display screen messages without coding any DSPF and using variable-length characters –  just for fun (Yes, I know, I need to get out more):

// --------------------------------------------------------------
RPG Code Snippet// Example SQL RPG program : VLD8EMAIL
// Author : Nick Litten
// History:
// 2012-06-12 NJL Created
// --------------------------------------------------------------
// This program accepts an input parameter of 'email address'.
// We validate it using a regular expression in SQL and
// display a message in a window telling you if the email
// address is good or bad. nice or naughty.
// Simple but Saucy.
// --------------------------------------------------------------

ctl-opt dftactgrp(*no)

// this is our program input a 255 long variable email
dcl-pi *n;  
  email varchar(255);

// this is our subprocedure - put this in a *SRVPGM to share it
dcl-pr email_is_valid IND; 
  *n like(email);

if email_is_valid(email);
  display_window ('Email Address ' + %trim(email) + ' is valid');
  display_window ('Yuk! Email Address ' + %trim(email) +
  ' is very naughty indeed. Bad Email! ');

*inlr = *on;

// --------------------------------------------------------------
// PROCEDURE: email_is_valid
// --------------------------------------------------------------
// Accept an input field (the email address) and validate it using
// a regular expression to perform basic email address syntax checks.
// REGEXP_COUNT Returns a returns a count of the number of times
// that a regular expression pattern is matched in a string
// The leading ^ and trailing $ match the beginning and the ending of
// the input string, respectively. That is, the entire input string
// shall match with this regexe, instead of a part of the input string.
// \w+ matches 1 or more word characters (a-z, A-Z, 0-9 and underscore).
// [.-] matches character . or -. We need to use . to represent . as . has
// special meaning in regexe. The \ is known as the escape code, which
// restore the original literal meaning of the following character.
// [.-]? matches 0 or 1 occurrence of [.-].
// ([.-]?\w+)* matches 0 or more occurrences of [.-]?\w+.
// The sub-expression \w+([.-]?\w+)* is used to match the username in
// the email, before the @ sign. It begins with at least one word
// character (a-z, A-Z, 0-9 and underscore), followed by more word
// characters or . or -. However, a . or - must follow by a word
// character (a-z, A-Z, 0-9 and underscore). That is, the string cannot
// contain "..", "--", ".-" or "-.". Example of valid string are "a.1-2-3".
// The @ matches itself.
// The sub-expression .\w{2,3} matches a . followed by two or three word
// characters, e.g., ".com", ".edu", ".us", ".uk", ".co".
// (.\w{2,3})+ specifies that the above sub-expression shall occur one or
// more times, e.g., ".com", ".co.uk", ".edu.sg" etc.
// --------------------------------------------------------------

dcl-proc email_is_valid;
dcl-pi *n IND;
  myEmail like(email);
dcl-s myCount uns(10);

// you can change this Regex string to anything you like!!!
dcl-s myEmailValidationRegex varchar(1024)

exec sql
   set :myCount = regexp_count(:myEmail,:myEmailValidationRegex);

 If myCount = 1;
   return *on;
   return *off;


// --------------------------------------------------------------
// PROCEDURE: display_window 
// --------------------------------------------------------------
// Use IBM i *API 'QUILNGTX' to dynamicalluy show messages in a 
// window format rather than on the error message line 
// --------------------------------------------------------------
dcl-proc display_window export;
 dcl-pi display_window;
   p_Text varchar(8192) const;
   p_MsgId char(7) Options(*nopass: *omit);
   p_MsgFile char(21) Options(*nopass: *omit);

 dcl-ds myApiError inz qualified;
   Bytes int(10) inz(%size(myApiError));
   BytesAvailable int(10) inz;
   ErrorID char(7) inz;
   Reserved char(1) inz(x'00');
   MessageData char(128) inz;

 dcl-pr QUILNGTX extpgm('QUILNGTX');
   *n char(8192) const;
   *n int(10) const;
   *n char(7) const;
   *n char(21) const;
   *n options(*omit: *varsize) like(myapierror);

 dcl-s myMsgId like(p_MsgId);
 dcl-s myMsgFile like(p_MsgFile);

 If %Parms = 1;
   myMsgId = 'CPF9999';
   myMsgFile = 'QCPFMSG';
 Elseif %Parms = 2;
   myMsgId = p_MsgId;
   myMsgFile = 'QCPFMSG';
 Elseif %Parms = 3;
   myMsgId = p_MsgId;
   myMsgFile = p_MsgFile;
 Endif ;

 QUILNGTX ( p_Text : %Len(p_Text) : myMsgId : myMsgFile : myApiError );


I hope that helps someone out?

Let’s test this SQLRPGLE code

Testing is easy – I just knocked together a little calling program, because calling variable-length input parameters from an IBM i command line is painful. Convert the previous code into a *SRVPGM (or copy/paste the code into the mainline) to add it to this example and:

// Example SQL RPG program : TESTEMAIL
// Author : Nick Litten
// History:
// 2014-06-12 NJL Created
// --------------------------------------------------------------
// call validation program with various VARCHAR email addresses
// --------------------------------------------------------------

ctl-opt dftactgrp(*no)

dcl-pr tst_email extpgm('VLD8EMAIL'); 
  *n varchar(255); 

dcl-s email varchar(255); 

email = 'nick@nicklitten.com'; 

email = 'nick@this-is_a@very$duff email'; 

*inlr = *on;

and when I call my TEST program I see these two sceeens:

Example RPG Email Validation program - SQLRPGLE ILE 1
Example RPG Email Validation program - SQLRPGLE ILE 2

PS: to test your regular expressions check out http://emailregex.com/regex-visual-tester/ it’s excellent!

Hope that helps some out?

Update Oct 2020

A new regex is shown over at email regex – I would love to know if this helps anyone?

General Email Regex (RFC 5322 Official Standard)



IBM i Software Developer, Digital Dad, AS400 Anarchist, RPG Modernizer, Shameless Trekkie, Belligerent Nerd, Englishman Abroad and Passionate Eater of Cheese and Biscuits. Nick Litten Dot Com is a mixture of blog posts that can be sometimes serious, frequently playful and probably down-right pointless all in the space of a day. Enjoy your stay, feel free to comment and remember: If at first you don't succeed then skydiving probably isn't a hobby you should look into.

Nick Litten

related posts:

  • Nice work documenting and commenting, as well as including a usable subprocedure and test. Do you know whether IBM’s SNDSMTPEMM supports recipient email addresses with the “.bz” domain? The command throws a TCP530F Email Address Invalid whenever I try to use it with “.bz” domains.

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
    __CONFIG_colors_palette__{"active_palette":0,"config":{"colors":{"cff50":{"name":"Main Accent","parent":-1},"a344d":{"name":"Accent Transparent","parent":"cff50"}},"gradients":[]},"palettes":[{"name":"Default","value":{"colors":{"cff50":{"val":"var(--tcb-skin-color-0)"},"a344d":{"val":"rgba(46, 138, 229, 0.85)","hsl_parent_dependency":{"h":210,"l":0.54,"s":0.78}}},"gradients":[]},"original":{"colors":{"cff50":{"val":"rgb(0, 178, 255)","hsl":{"h":198,"s":1,"l":0.5}},"a344d":{"val":"rgba(0, 178, 255, 0.85)","hsl_parent_dependency":{"h":198,"s":1,"l":0.5}}},"gradients":[]}}]}__CONFIG_colors_palette__

    Get In Touch

    I’m always looking for awesome input, feedback and critique!