xsharp.eu • Validate email adress
Page 1 of 1

Validate email adress

Posted: Thu Feb 23, 2023 8:42 pm
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

Validate email adress

Posted: Thu Feb 23, 2023 8:55 pm
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

Validate email adress

Posted: Fri Feb 24, 2023 8:45 am
by robert
Dick,
I think the DomainMapper() function is missing from your example.

Robert

Validate email adress

Posted: Fri Feb 24, 2023 10:17 am
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

Validate email adress

Posted: Fri Feb 24, 2023 2:21 pm
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

Validate email adress

Posted: Mon Feb 27, 2023 5:23 pm
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

Validate email adress

Posted: Mon Feb 27, 2023 5:49 pm
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

Validate email adress

Posted: Thu Mar 02, 2023 4:07 pm
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