Это регулярное выражение сделает это (включая диакритические знаки):
/^(([().!#$%&'*+\/=?^_`{|}~\u00BF-\u1FFF\u2C00-\uD7FF\w-]+[,\n#\s$&:\n\t]+){2,}){0,}(?:<){0,1}[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9]))(?:>){0,1}$/igm
Следующая строка проверяет имена, включая диакритические знаки \u00BF-\u1FFF\u2C00-\uD7FF\w-
(не адрес электронной почты). Он упакован в группу захвата, которая оценивает наличие имен. Если есть имена Вторая группа захвата в пределах проверок, если есть хотя бы два {2,}
. Это сжатая версия, поскольку нам не нужно различать имя и фамилию.
* <>
заключены в группы без захвата и должны встречаться ноль или один раз.
/(([().!#$%&'*+\/=?^_`{|}~\u00BF-\u1FFF\u2C00-\uD7FF\w-]+[,\n#\s$&:\n\t]+){2,}){0,}/
const regEx = /^(([().!#$%&'*+\/=?^_`{|}~\u00BF-\u1FFF\u2C00-\uD7FF\w-]+[,\n#\s$&:\n\t]+){2,}){0,}(?:<){0,1}[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9]))(?:>){0,1}$/ig;
const emails = document.querySelectorAll("div");
emails.forEach(element => {
if (element.textContent.match(regEx))
{
element.classList.add("match");
}
});
div.match {
color: #ff0000;
}
<div>test@test.com</div>
<div><test@test.com></div>
<div>Näme Surmame <test@test.com></div>
<div>Name, Surname <test@test.com></div>
<div>Name 北京市 Surname surname2 Surname3 <test@test.com></div>
<div>Name (name 2), Surname-surname2 <test@test.com></div>
<div>Name <test@test.com></div>
<div>test @test.com</div>
<div>isthis3avalid test <test@test></div>
</textarea>