nine / solution 9.1
<?php
function mineEmails(string $t)
{
$t = trim($t);
if (!strlen($t)) {
print_r("<p>no emails found because text was blank.</p>");
return;
}
$t = mb_convert_case($t, MB_CASE_LOWER);
preg_replace_callback("/[a-z0-9!#%\$&\'\*\+\-\/\=\?\^_`\{|\}~\.]+\@[a-z0-9\-]+(?:\.[a-z0-9\-]+)+/", "addEmail", $t);
}
function addEmail($e)
{
global $emails;
$e = $e[0];
(!isset($emails) || !count($emails)) && ($emails = []);
$e = verifyEmail($e);
$e && strlen($e) && !in_array($e, $emails) && ($emails[] = $e) && natsort($emails);
}
function showEmails()
{
global $emails;
if (!isset($emails) || !count($emails)) {
return;
}
print_r("<ul>");
array_map(fn($e) => print_r("<li>" . $e . "</li>"), $emails);
print_r("</ul>");
}
function verifyEmail(string $e)
{
// check for basic pattern ([email protected])
if (!preg_match("/.+@.+\..+/", $e)) {
return false;
}
// convert to lowercase
$e = mb_convert_case($e, MB_CASE_LOWER);
// eliminate whitespace
$e = preg_replace("/\s+/", "", $e);
// simplify consecutive periods
$e = preg_replace("/\.+/", ".", $e);
// split email into name and domain because their constraints are different
$name = explode("@", $e)[0];
$domain = explode("@", $e)[1];
// check for both elements
if (!strlen($name) || !strlen($domain)) {
return false;
}
// remove leading/trailing periods
$name = trim($name, ".");
$domain = trim($domain, ".");
// remove invalid characters from both sections
$name = preg_replace("/[^a-z0-9!#%\$&\'\*\+\-\/\=\?\^_`\{|\}~\.]/", "", $name);
$domain = preg_replace("/[^a-z0-9\-\.]/", "", $domain);
// crop name to 64 characters
$name = substr($name, 0, 64);
// crop each domain segment to 63 characters
$domain = explode(".", $domain);
foreach ($domain as &$i) {
$i = substr($i, 0, 63);
}
$domain = implode(".", $domain);
// check for both elements again (in case all characters were invalid)
if (!strlen($name) || !strlen($domain)) {
return false;
}
// rebuild email
$e = $name . "@" . $domain;
return $e;
}
isset($_POST) && isset($_POST["source"]) ? mineEmails($_POST["source"]) : print_r("<p>please submit text to parse.</p>");
isset($emails) && count($emails) && showEmails();