Validate email adress

This forum is meant for questions and discussions about the XSharp Tools libraries, which contain code written by XSharp users that they want to share with others,
The development team is not responsible for this code

Moderator: wriedmann

Post Reply
User avatar
Horst
Posts: 327
Joined: Tue Oct 13, 2015 3:27 pm

Validate email adress

Post by Horst »

Hello
Before i start to write it by myself , has somebody a x# function to validate a email adress and woud like to share it?

Horst
ic2
Posts: 1798
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

Validate email adress

Post by ic2 »

Hello Horst,

Here you go:

Code: Select all

Method IsValidEmail(strIn As String) As Logic
//#s Check if email string is valid DvK 16-10-2014
//#l Translated from C# from http://msdn.microsoft.com/en-us/library/vstudio/01escwtf%28v=vs.100%29.aspx
strIn:=alltrim(strIn)
Self:lInvalid:=False
If (STRING.IsNullOrEmpty(strIn))
	Return False
Endif
strIn := System.Text.RegularExpressions.Regex.Replace(strIn, "(@)(.+)$", System.Text.RegularExpressions.MatchEvaluator{ Self, @DomainMapper() })
If (Self:lInvalid)
	Return False
Endif
Return System.Text.RegularExpressions.Regex.IsMatch(strIn, "^(?("+chr(34)+")("+chr(34)+"[^"+chr(34)+"]+?"+chr(34)+"@)|(([0-9a-z]((.(?!.))|[-!#$%&"+chr(39)+"*+/=?^`{}|~w])*)(?<=[0-9a-z])@))(?([)([(d{1,3}.){3}d{1,3}])|(([0-9a-z][-w]*[0-9a-z]*.)+[a-z0-9]{2,17}))$", System.Text.RegularExpressions.RegexOptions.IgnoreCase)


Private Method DomainMapper(match As System.Text.RegularExpressions.Match) As String
//#s Used by IsValidEmail DvK 16-10-2014

Local idn As System.Globalization.IdnMapping
Local domainName As String
	idn := System.Globalization.IdnMapping{}
	domainName := match:Groups:Item[2]:Value
	Try
		domainName := idn:GetAscii(domainName)
	Catch e As System.ArgumentException
		Local cMessage:=e:Message As String
		Self:lInvalid := True
	End Try
Return STRING.Concat(match:Groups:Item[1]:Value, domainName)


Dick
User avatar
robert
Posts: 4225
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

Validate email adress

Post by robert »

Dick,
I think the DomainMapper() function is missing from your example.

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
ic2
Posts: 1798
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

Validate email adress

Post by ic2 »

Hello Robert,
robert post=25362 userid=253 wrote: I think the DomainMapper() function is missing from your example.
Indeed! I added it now.

Dick
User avatar
Horst
Posts: 327
Joined: Tue Oct 13, 2015 3:27 pm

Validate email adress

Post by Horst »

Hello Dick
Thanks for your example. I saw also some like that in c# , but i wanna have a solution closer to Clipper style.
Your example will be more exactly then my one i think (unicode annd äöü) but your calling so many resources to check just a email adress.
So i wrote a simpler code and i think and hope that will work for 99% normal email adresses.

Code: Select all

FUNCTION IsValidEMail (cString AS STRING )  AS LOGIC
	LOCAL cTestString 	:= "abcdefghijklmnopqrstuvwxyz0123456789.!@#$%&*+-/=?^_'{}|~`"	AS STRING       
	LOCAL nCnt		AS DWORD
	LOCAL nLen		AS DWORD
	LOCAL nPos		AS DWORD
	LOCAL cDomain		AS STRING
	
	cString := Lower 	(AllTrim(cString))      
	nLen 	:= SLen 	(cString)
	
	// allowed chars ?
	FOR nCnt := 1 UPTO nLen
		IF At2 (SubStr3 (cString,nCnt,1), cTestString) = 0
			RETURN FALSE
		ENDIF     
	NEXT nCnt 
	
	// @ only one allowed
	nCnt := Occurs ("@", cTestString)
	IF nCnt = 0 .or. nCnt > 1
		RETURN FALSE
	ENDIF     
	
	// Domain
	   	nPos 	:= At2 ("@", cString)  
   		cDomain := SubStr2 (cString, nPos+1)
		// Dot at the end error
		IF SubStr3 (cString, nLen, 1 ) = "."   	
			RETURN FALSE
		ENDIF
		// dot at first in domain error	
		IF SubStr3 (cDomain, 1, 1 ) = "."   	
			RETURN FALSE
		ENDIF    
		// . only one allowed
		nCnt := Occurs (".", cDomain)
		IF nCnt = 0 .or. nCnt > 1
			RETURN FALSE
		ENDIF         
		// space not allowed
		IF At2 (" ", cDomain) > 0
			RETURN FALSE
		ENDIF         

		// evt. ping the domain
	RETURN TRUE          

Horst
User avatar
ArneOrtlinghaus
Posts: 384
Joined: Tue Nov 10, 2015 7:48 am
Location: Italy

Validate email adress

Post by ArneOrtlinghaus »

This is what we use. Nearly all users have email addresses with English characters. But we had already few exceptions, I believe with some accent characters used in Italian. So we needed already the possibility to allow exceptional special characters where we normally want to treat them as errors.

method VerifyEmailRecipient (cEMailRecipientValue, coptions) as usual clipper
local cchl, cch, c as string
local a as array
local n, ich, ipart as dword
local cerror := "" as string
c := cEMailRecipientValue
local cemailallowedcharacters := ".@!#$%&'*+-/=?^_`{|}~äöüàèé" as string
// zum leichten Hinzufügen von Extrazeichen über Login-Makro
// Unter Umständen ist sinnvoll, diese in der obenstehenden Zeile fest hinzuzufügen
cemailallowedcharacters += lower(getglobal (#emailallowedcharacters, ""))

// The local-part of the email address may use any of these ASCII characters:
// uppercase and lowercase Latin letters A to Z and a to z;
// digits 0 to 9;
// special characters !#$%&'*+-/=?^_`{|}~;
// dot ., provided that it is not the first or last character unless quoted, and provided also that it does not appear consecutively unless quoted (e.g. John..Doe@example.com is not allowed but "John..Doe"@example.com is allowed);
// space and "(),:;<>@[] characters are allowed with restrictions (they are only allowed inside a quoted string, as described in the paragraph below, and in addition, a backslash or double-quote must be preceded by a backslash);
// comments are allowed with parentheses at either end of the local-part; e.g. john.smith(comment)@example.com and (comment)john.smith@example.com are both equivalent to john.smith@example.com.
a := string2array(alltrim(c), ";")
for ipart := 1 upto alen(a)
c :=a[ipart]
if !Empty(c)
for ich := 1 upto slen(c)
cch := charpos(c, ich)
cchl := lower(cch)
if !Between (cchl, "0", "9") .and. !Between (cchl, "a", "z") .and. !instr(cchl, cemailallowedcharacters)
cerror := Msg(20018/*ID_NICHT_ERLAUBTE_ZEICHEN*/) +": " + cch
if !(cch==cchl)
cerror += " ("+cchl+")"
endif
endif
if !Empty(cerror)
exit
endif
next
n := occurs("@", c)
if n == 0
cerror := Msg(51758/*ID_DAS_ZEICHEN_PROZ1_WURDE_NICHT_GEFUNDEN*/, "@")
elseif n > 1
cerror := Msg(51759/*ID_DAS_ZEICHEN_PROZ1_WURDE_MEHRMALS_VERWENDET*/, "@")
endif
if instr("..", c)
cerror := Msg(51759/*ID_DAS_ZEICHEN_PROZ1_WURDE_MEHRMALS_VERWENDET*/, ".")
endif
if !Empty(cerror)
exit
endif
endif
next
if !Empty(cerror)
cerror := Msg(51760/*ID_DIE_E_MAIL_ADRESSE_ENTSPRICHT_NICHT_UEBLICHEN_R*/)+": " + cEMailRecipientValue+" - " + cerror
endif
return cerror
ic2
Posts: 1798
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

Validate email adress

Post by ic2 »

Hello Horst,
Horst post=25397 userid=315 wrote: Thanks for your example. I saw also some like that in c# , but i wanna have a solution closer to Clipper style.
Your example will be more exactly then my one i think (unicode annd äöü) but your calling so many resources to check just a email adress.
So i wrote a simpler code and i think and hope that will work for 99% normal email adresses.
[/code]
Probably, the 99%.

But the above code works and I have never had a reosurce shortage during a day of sending mails.

Personally I always prefer working code which is not to bulky and which I can add directly above re-inventing the wheel with probably a less accurate result B)

Dick
User avatar
Horst
Posts: 327
Joined: Tue Oct 13, 2015 3:27 pm

Validate email adress

Post by Horst »

Hello Dick

I am using my little function now with some addtional chars from Arne, but i was copy and paste your solution into my sourcefile, so i can switch if necessary. ;-)

Thanks
Post Reply