JavaScript Regular Expression for separating a collection of email addresses into individual parts

I am very close to getting this to work, but not quite there yet.

In my JavaScript code, I have a string with a list of email addresses, each formatted differently:

var emailList = '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5525302130271525343b7b363a38">[email protected]</a>, 
lucky <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4b212a28200b3b243f65282426">[email protected]</a>>, 
"William Tell" <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="197b7075756059... (content truncated for uniqueness)

My first task is to split this string into individual emails. Emails are separated by ', ':

<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9cecf9e8f9eedcecfdf2b2fff3f1">[email protected]</a>, lucky <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7913181a123909160d571a1614">[email protected]</a>>

However, the separator ', ' might also appear within names enclosed in quotes:

"John Rambo, III" <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b6dcd9ded8d8cff6c4d7dbd4d998d5d9db">[email protected]</a>>

There can even be multiple commas inside quotes:

"there, might, be, several, commas inside the quotes" <<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="65081009110c15090025060a08080416... (content truncated for uniqueness) 

Step 1: replacing commas enclosed in quotes

I want to replace these commas with something like

<<<<!!!!>>>>

I attempted to achieve this using a regex pattern, but it's not working as expected:

(".*)(,)(\s.*"), $1<<<<!!!!>>>>$3

Step 2: splitting the array and reverting comma substitution

This can now be easily done with JavaScript using split and replace:

var Array = emailList.split(', ');
Array.forEach(function(element, index, arr) {
  arr[index] = element.replace("<<<<!!!!>>>> ", ", ");
});

At this stage, I should have an array where each element represents an email in a specific format. Next step is to break down each individual email into its basic components.

Step 3: breaking down email addresses

To extract the relevant information from each email, including full name, first word, local part, and company, I'll need to use various regular expressions.

Overall Goal:

I'm looking for assistance to complete steps 1 and 3 more efficiently. Any optimized regex patterns or suggestions on how to improve the process would be greatly appreciated!

While it's not necessary, if you're able to craft a single magical RegExp that accomplishes the desired email breakdown, I will be thoroughly impressed and humbled by your Regex expertise! :)

Thank you for your help!

Answer №1

I propose that achieving your desired outcome is possible with the following regex pattern:

(?:(?:"?((\w+)\b.*\b)"?)\s)?<?(([\w@]*)@(\w*)\.[a-zA-Z]{2,3})>?,?

and utilizing the replacement code:

{ fullName:'\1', firstWord:'\2', localPart:'\4', company:'\5', email:'\3'}

Check out the Demo

Answer №2

To split a string at commas excluding those within quotes, you can utilize the regex pattern shown here:

,(?=(?:[^'"]|'[^']*'|"[^"]*")*$)

With this method, you can skip steps 1 and 2.

As for the ineffective patterns in step 3:

This pattern fails as it captures trailing "

  • (?|"(\[^"\]+)"|(.*) <): initially matches balanced quotes or anything before <.
    Note: Group 2 must be checked if group 1 is empty (unfortunately, JS does not support branch reset groups).

This pattern fails to capture "peter" in "peter@pan"

  • (<|^)(.*)@: could potentially match starting from the beginning;
    however, anchoring the pattern correctly poses challenges.

For email validation, consider using one of the established and recommended solutions provided here and on this website. However, that's a separate discussion altogether.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble mapping an array of objects in ReactJS

I'm encountering an issue where I am unable to map through an array of objects in my component. Although I have used this map method before, it doesn't seem to be working now. Can anyone help me figure out what's going wrong? import React, ...

Google Charts is unable to display any data because the table does not contain

After browsing numerous forums and attempting various solutions, I encountered a new challenge each time. My goal is to generate a Google line chart using data from a MYSQL table and encoding it in JSON. Then, I aim to utilize an HTML file to showcase the ...

Prevent the execution of useEffect on the client side in Next JS if the data has already been retrieved from the server

Upon loading the server side rendered page, data is fetched on the server and passed to client side components. To handle this process, a hook has been created with a state that updates based on checkBox changes. When the state changes, a useEffect is tri ...

Having trouble with uploading a file through ajax

I'm currently working on uploading form data through ajax, but I've encountered an issue with uploading images/files. Form Code <form class="form-inline" id="form_add" enctype="multipart/form-data"> <input type="file" id="file-inpu ...

IDEA 2021.2 NPM SCRIPTS: Looks like there are no scripts available

Searching through the npm scripts, I am unable to locate any, however package.json does contain: ...

Swagger is unable to locate a user schema when utilizing Yaml files

Hello, I am a beginner using Swagger and trying to create simple endpoint documentation. However, I am facing an issue with my schema type and cannot figure out what's wrong. To start off, I organized my folder structure in the root src directory whe ...

The dynamic relationship between redux and useEffect

I encountered a challenge while working on a function that loads data into a component artificially, recreating a page display based on the uploaded data. The issue arises with the timing of useEffect execution in the code provided below: const funcA = (p ...

Retrieve the highest integer from the server-side for the client

When creating input fields of type number on the client side, I have been setting their max attribute to the maximum integer value in the user's browser using: Number.MAX_SAFE_INTEGER.toString() Now, I need to output an input field on the se ...

Tips for customizing the appearance of popup windows

I want to enhance the appearance of my popup window by applying a different format for opening it. How can I style it so that it looks visually appealing when the popup window opens? You can find below the source code I am working with: HTML: <div onM ...

Top method for implementing select all checkboxes in a table

Hey there! I'm new to VueJS and I've been working on creating a data table component. So far, I have built two components called ui-datatable and ui-checkbox, which allow me to select all rows in the table. It's functioning perfectly fine, b ...

An easy way to attach a Contextmenu to a specific element

I have implemented a scrolling feature for one of the div elements in my Application. Inside this div, there is a templated table with over 100 rows. Users are able to add or delete rows using a contextMenu. The contextMenu offers 4 options - AddTop, AddB ...

Clicking on a button will trigger the opening of a modal dialog

I encountered an issue with the following code: <sepa-modal ref="sepaModal" /> <b-card id="show-btn" class="card-modal" @click="openSepaModal()" > </b-card> openSepaModal ...

Troubleshooting Angular 2: Instances of Classes Not Being Updated When Retrieving Parameters

I am facing an issue with the following code snippet: testFunction() { let params = <any>{}; if (this.searchTerm) { params.search = this.searchTerm; } // change the URL this.router.navigate(['job-search'], {q ...

Building Next.js with a designated maximum number of processes/threads

I've uploaded a fresh Next.js app to the cloud server using npx create-next-app. However, when I try to run the build script, the server throws an error 'pthread-create: Resource temporarily unavailable'. { "name": "next&quo ...

Endless asynchronous loops with setInterval()

My nodejs application requires multiple infinite loops that call asynchronous functions. I was contemplating the following approach: async function process1() { ...perform some asynchronous tasks... } async function process2() { ...perform some as ...

Is it possible to declare variables within a React 'render' function?

I have data arranged in multiple columns on several rows, with a react element corresponding to each data element. The number of elements on the first row can vary between 4 and 6. For instance, I may display a user's name, birthday, and email. If t ...

Show singular array element upon click

I need help with a specific task. When a button is clicked, I want to display a random item from an array. Each array item should only be displayed once. Currently, my code is set up as follows: When the button is clicked, a random array item is displ ...

What is the correct location to define the "env" setting in the eslint.config.js file?

In 2022, ESLint rolled out a new configuration system called the "flat config" here. Check out the documentation for the new "flat config". | Old configuration system documentation here. The "flat config" documentation shows that the `eslint.config.js` ...

Creating a custom event for every reference within a Vuejs for loop

I'm working with a loop of data and have a modal for each iteration <div ref="vuemodal-{{loop.index}}"> Each modal is a bootstrap modal, and I want to bind an event to them that triggers whenever the modal is closed mounted(){ Obj ...

Creating a Custom Select Option Component with Ant Design Library

Is it possible to customize options in an antd select component? I have been trying to render checkboxes alongside each option, but I am only seeing the default options. Below are my 'CustomSelect' and 'CustomOption' components: // Cu ...