Callum Linington
Callum Linington

Reputation: 14417

JavaScript split string around emails

So I have this list of emails:

[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

It comes through as a string, sometimes with a return character at the end of each line, sometimes it doesn't. All I want to be able to do is pull out each email from the string using regex.

So I've got this regex exp from here:

function validateEmail(email) { 
    var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(email);
} 

How do I get it to match many email addresses and return me each individual email?

I do not want to split on a return character, I can't always garauntee that it will be that character that will split the list up. These emails are pasted in from the users clipboard. If it were that easy, I wouldn't have asked ;)

Upvotes: 0

Views: 1632

Answers (3)

Ian Hazzard
Ian Hazzard

Reputation: 7771

Here's a VERY simple way to do it.

/([^;:<>!?\n]+\@[^;:<>!?\n]+\.[^;:<>!?\n]+)/gmi

Explanation:

The [^;:<>!?\n] matches everything EXCEPT those characters. So [^;:<>!?\n]+ just means match everything but these as many times as needed.

Then match an @ symbol.

Then match as many of NOT these ([^;:<>!?\n]) as needed again.

Then match a literal dot (.).

Then DON'T match these ([^;:<>!?\n]) again.

The gmis at the end are called flags. They mean:

  1. g means global. Match this RegEx over and over.
  2. m means multi-line. Don't stop at the end of the first line of emails.
  3. i means insensitive. Don't worry about the upper and lower cases.

Demonstrations here: https://regex101.com/r/aC5cK2/1

Upvotes: 2

Callum Linington
Callum Linington

Reputation: 14417

So I have re work the answer to incorporate what @adeneo said:

$scope.pasteThis = function(e) {
    var emails = e.clipboardData.getData('text/plain');

    var emailArray = emails.split(/(\n|\s|,)/);

    angular.forEach(emailArray, function (e) {
        var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;

        if (EMAIL_REGEXP.test(e)) {
            if (!contains($scope.emailAddresses, e)) {
                $scope.emailAddresses.push(e);
            }
        }
    });
}

function contains(arr, el) {
    var found = false;
    angular.forEach(arr, function(e) {
        if (e == el) {
            found = true;
        }
    });

    return found;
}

So EMAIL_REGEXP is from the Angular source code. I use that in other places so it is very appropriate to use it here (consistency).

This function makes sure that after the emails are split, each one is a valid email address. This means that no mess can get through.

Upvotes: 0

adeneo
adeneo

Reputation: 318302

It comes through as a string, with a return character at the end of each line.

Then just split the string on newlines ?

var email_array = str.split("\n");

Upvotes: 2

Related Questions