Jump to content
Ian Branch

Regex help please..

Recommended Posts

Hi Team,

Regex is one of those mysteries I have never fathomed. :-(

I have the following code..

function ValidEmail(const EmailAddress: string): Boolean;
const
  EMAIL_REGEX = '^((?>[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+\x20*|"((?=[\x01-\x7f])' + '[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)' +
    '(?>\.?[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+)+|"((?=[\x01-\x7f])' + '[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]' +
    '{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d))' + '{4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])[^\\\[\]]|\\' +
    '[\x01-\x7f])+)\])(?(angle)>)$';
begin
  Result := IsMatch(EmailAddress, EMAIL_REGEX);
end;

I don't recall exactly where I found it, apologies to the author, and it has served me well.

It works well for single email address entries.

How can it be modified so that it will parse multiple email addresses separated by a ';'?

e.g. myemail@here.com;youremail@there.com.au

With possible expansion to three or more email addresses in the future.

I will be most grateful for any solution.

 

Regards & TIA,

Ian

Share this post


Link to post

I think I would split the string on semicolons and run the regex on each individual address.

function ValidEmail(const EmailAddress: string): Boolean;
const
  EMAIL_REGEX = '^((?>[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+\x20*|"((?=[\x01-\x7f])' + '[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)' +
    '(?>\.?[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+)+|"((?=[\x01-\x7f])' + '[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]' +
    '{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d))' + '{4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])[^\\\[\]]|\\' +
    '[\x01-\x7f])+)\])(?(angle)>)$';
var
  Emails: TStringList;
begin
  Result := True;

  Emails := TStringList.Create;
  try
    Emails.Delimiter := ';';
    Emails.StrictDelimiter := True;
    Emails.DelimitedText := EmailAddress;
    for var i := 0 to Emails.Count - 1 do
      if not IsMatch(Emails[i], EMAIL_REGEX) then
      begin
        Result := False;
        Break;
      end;
  finally
    Emails.Free;
  end;
end;

 

  • Like 2

Share this post


Link to post

Hi David,

Doh!!  This is where I face palm myself and berate myself for not thinking of that. 😞

Thank you for pointing out my inadequacy. 🙂

 

Regards & Tks again,

Ian

 

Share this post


Link to post
  EMAIL_REGEX = '^((((?>[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+\x20*|"((?=[\x01-\x7f])' + //
    '[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)' + //
    '(?>\.?[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+)+|"((?=[\x01-\x7f])' + //
    '[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]' + //
    '{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d))' + //
    '{4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])[^\\\[\]]|\\' + //
    '[\x01-\x7f])+)\])(?(angle)>))(;\S)*)+$';

eventually

 

 

Share this post


Link to post

Hi Attila,

Thank you for your contribution.

Given that I have no idea about regex I can only wonder at what you have done.

 

Regards,

Ian

Share this post


Link to post

@Fr0sT.Brutal speaking of International Domain Names any ideas
 

I still have to validate the

  1. Latin alphabet with diacritics       Pelé@example.com
  2. Greek alphabet                           δοκιμή@παράδειγμα.δοκιμή
  3. Traditional Chinese characters     我買@屋企.香港
  4. Japanese characters                    二ノ宮@黒川.日本 
  5. Cyrillic characters                        медведь@с-балалайкой.рф 
  6. Devanagari characters                संपर्क@डाटामेल.भारत   

using the same RegEx as OP

Share this post


Link to post
On 9/19/2021 at 11:53 PM, Attila Kovacs said:

  EMAIL_REGEX = '^((((?>[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+\x20*|"((?=[\x01-\x7f])' + //
    '[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)' + //
    '(?>\.?[a-zA-Z\d!#$%&''*+\-/=?^_`{|}~]+)+|"((?=[\x01-\x7f])' + //
    '[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]' + //
    '{2,}|\[(((?(?<!\[)\.)(25[0-5]|2[0-4]\d|[01]?\d?\d))' + //
    '{4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])[^\\\[\]]|\\' + //
    '[\x01-\x7f])+)\])(?(angle)>))(;\S)*)+$';

eventually

 

 

You have a problem.
You apply RegEx to solve the problem.
You now have two problems.
:classic_rolleyes:

  • Like 1
  • Haha 4

Share this post


Link to post
17 minutes ago, Lars Fosdal said:

You now have two problems.

\p{L}+([-+.']\p{L}+)*@\p{L}+([-.]\p{L}+)*\.\p{L}+([-.]\p{L}+)*$

 

image.png.e6a06b763359f817d7368c4e3a66dc02.png

 

 

image.thumb.png.19c4a512278e77ef8a8f837b640f5da4.png

 

 

the devanagari fails

 

 

Edited by Attila Kovacs
  • Haha 1

Share this post


Link to post
44 minutes ago, Timothy.Prinsloo said:

out of interest

there is a PCRE regex in newer Delphi releases, yes, at some degree it will work

  • Like 1

Share this post


Link to post

Given the complexity and the tendency of developers to always suggest some totally different approach :classic_biggrin:, here is my completely different suggestion. You seem to have the need to validate an e-mail address before storing it. How about sending a test mail before doing that. That way you get to birds with one stone: Verify the address, and get the permission to use it... a must have in Europe.

  • Like 1

Share this post


Link to post
10 minutes ago, Sherlock said:

Given the complexity and the tendency of developers to always suggest some totally different approach :classic_biggrin:, here is my completely different suggestion. You seem to have the need to validate an e-mail address before storing it. How about sending a test mail before doing that. That way you get to birds with one stone: Verify the address, and get the permission to use it... a must have in Europe.

This is an excellent suggestion. I doubt it is a must in Europe, I still receive sensitive information for other people in my e-mail account. 

Share this post


Link to post
20 minutes ago, Sherlock said:

How about sending a test mail before doing that

It's a very-very bad suggestion. You should read an article how not to get into a spam db. First, you have to avoid sending emails to malformed email addresses.

 

20 minutes ago, Sherlock said:

a must have in Europe

Nope. Also, there is a difference between private/non ~ emails, first / second+ contact, etc....

 

 

Share this post


Link to post

I'd rather ask myself WHY I need such validation. Email "rubba@hubba.bubba" will pass any checks but won't gain any sense.

Domain check? They're multiplying like rabbits so you'll have to keep regex up to date + it won't save from "rubba@hubba.com" emails.

 

  • Like 1

Share this post


Link to post
3 minutes ago, Fr0sT.Brutal said:

I'd rather ask myself WHY I need such validation

I have it for two reasons, first, ppls. manual input is messy, second, if they copy-paste from websites it can be a strange thing in the edit field and they don't look.

Share this post


Link to post
4 minutes ago, Attila Kovacs said:

I have it for two reasons, first, ppls. manual input is messy, second, if they copy-paste from websites it can be a strange thing in the edit field and they don't look.

For these purposes simple NonSpace{1,}@NonSpace{1,}.NonSpace{2,} will be enough IMHO

Share this post


Link to post
23 minutes ago, Fr0sT.Brutal said:

For these purposes simple NonSpace{1,}@NonSpace{1,}.NonSpace{2,} will be enough IMHO

Yup.

Share this post


Link to post

@Attila Kovacs & @Lars Fosdal Thanks for all the help. I went with this as my solution

 EMAIL_REGEX = '^((((?>[a-zA-Z\d!#$%&’“”''*+\-\/=?^_`{|}~]+\x20*|"((?=[\x01-\x7f])'
               +'[^"\\]|\\[\x01-\x7f])*"\x20*)*(?<angle><))?((?!\.)'
               +'(?>\.?[a-zA-Z\d!#$%&’“”''*+\-\/=?^_`{|}~]+)+|"((?=[\x01-\x7f])'
               +'[^"\\]|\\[\x01-\x7f])*")@(((?!-)[a-zA-Z\d\-]+(?<!-)\.)+[a-zA-Z]{2,}|(((?(?<!)\.)'
               +'(25[0-5]|2[0-4]\d|[01]?\d?\d)){4}|[a-zA-Z\d\-]*[a-zA-Z\d]:((?=[\x01-\x7f])'
               +'[^\\\[\]]|\\[\x01-\x7f])+)\])(?(angle)>))(;\S)*)+$|'
               +'(\p{L}+([-+.]\p{L}+)*@\p{L}+([-.]\p{L}+)*\.\p{L}+([-.]\p{L}+)*$)';

Share this post


Link to post
On 12/14/2022 at 11:44 AM, Attila Kovacs said:

First, you have to avoid sending emails to malformed email addresses.

I would have put that check into an SMTP server. And...surprisingly the good ones do that.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×