如何从长字符串中获取电子邮件地址
Posted
技术标签:
【中文标题】如何从长字符串中获取电子邮件地址【英文标题】:How to get email address from a long string 【发布时间】:2010-11-04 22:33:48 【问题描述】:在 php 中,我有一个这样的字符串:
$string = "user@domain.com MIME-Version: bla bla bla";
如何仅获取电子邮件地址?有没有简单的方法来获取价值??
【问题讨论】:
【参考方案1】:以 mandaleeka 的回答为基础,使用空格分隔符分解字符串,然后使用 filter_var 进行清理,然后验证剩余的是否是合法的电子邮件地址:
function extract_email_address ($string)
foreach(preg_split('/\s/', $string) as $token)
$email = filter_var(filter_var($token, FILTER_SANITIZE_EMAIL), FILTER_VALIDATE_EMAIL);
if ($email !== false)
$emails[] = $email;
return $emails;
【讨论】:
失败的字符串案例:=?UTF-8?B?RXhwZXJ0IEFkdmlzb3I=?=example@blahblah.com
在 Sachin kumar 上失败
这不起作用例如:send email to a@a.com.
(注意末尾的点)【参考方案2】:
如果您不确定空格分隔字符串的哪一部分是电子邮件地址,您可以将字符串用空格分隔并使用
filter_var($email, FILTER_VALIDATE_EMAIL)
在每个子字符串上。
【讨论】:
从 PHP 5.2 开始,您可以使用 filter_var_array() 代替循环分割字符串的每一部分 请注意,空格可能是有效电子邮件地址的一部分(不常见但允许)。此答案中建议的方法不适用于这些电子邮件地址。见en.wikipedia.org/wiki/Email_address#Examples【参考方案3】:基于康斯坦丁正则表达式.. 也适用于 IP 地址域。
$pattern="/(?:[A-Za-z0-9!#$%&'*+=?^_`|~-]+(?:\.[A-Za-z0-9!#$%&'*+=?^_`|~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)3(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[A-Za-z0-9-]*[A-Za-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/";
//$pattern="/[A-Za-z0-9_-]+@[A-Za-z0-9_-]+\.([A-Za-z0-9_-][A-Za-z0-9_]+)/";
$subject="Hello a@b.com francis a@b words francisfueconcillo@gmail.com words 2 words123 francis@192.168.0.1";
preg_match_all($pattern, $subject, $matches);
【讨论】:
【参考方案4】:更新@Rob Locken 的答案:
function extract_email_address ($string)
$emails = array();
$string = str_replace("\r\n",' ',$string);
$string = str_replace("\n",' ',$string);
foreach(preg_split('/ /', $string) as $token)
$email = filter_var($token, FILTER_VALIDATE_EMAIL);
if ($email !== false)
$emails[] = $email;
return $emails;
【讨论】:
【参考方案5】:这个小的 PHP 脚本将帮助我们从长段落或文本中提取电子邮件地址。只需复制粘贴此脚本并将其保存为 PHP 文件 (extract.php):
$string="user@domain.com MIME-Version: bla bla bla";
$pattern="/(?:[a-z0-9!#$%&'*+=?^_`|~-]+(?:\.[a-z0-9!#$%&'*+=?^_`|~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)3(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/";
preg_match_all($pattern, $string, $matches);
foreach($matches[0] as $email)
echo $email.", ";
?>
上面的脚本会产生这样的结果:
user@domain.com,
【讨论】:
【参考方案6】:使用正则表达式过滤电子邮件地址非常棘手,因为有很多可能的允许字符。可以做到,但您可能需要对其进行一些调整才能得到您所需要的。
你可以这样开始:
$string = "user@domain.com MIME-Version: bla bla bla";
$matches = array();
$pattern = '/[A-Za-z0-9_-]+@[A-Za-z0-9_-]+\.([A-Za-z0-9_-][A-Za-z0-9_]+)/'
preg_match($pattern,$string,$matches);
然后 $matches 应该包含您的电子邮件地址。
【讨论】:
与 user.something@gmail.com 不匹配 2 个错误。第一个模式部分缺少点,第 3 行缺少分号【参考方案7】:如果电子邮件地址始终位于字符串的最前面,最简单的获取方法是将字符串拆分为空格字符的所有实例,然后从结果数组中取出第一个值。
当然,在使用它之前,请确保检查它是否类似于电子邮件地址。
详情请参阅 PHP 的“拆分”函数。
【讨论】:
【参考方案8】:这对我有用
(?:[a-z0-9!#$%&'*+/=?^_`|~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`|~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)3(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
检测字符串中的任何电子邮件地址
【讨论】:
【参考方案9】:$text = 'First Last <name@example.com>'
$emails = array_filter(filter_var_array(filter_var_array(preg_split('/\s/', $text), FILTER_SANITIZE_EMAIL), FILTER_VALIDATE_EMAIL));
【讨论】:
【参考方案10】:如果真的是空格分隔:
php > $matches = array();
php > preg_match('/^[^ ]*/', $string, $matches);
php > print_r($matches[0]);
user@domain.com
【讨论】:
【参考方案11】:看看Regular expressions in PHP。
使用正则表达式,您可以识别给定字符串中的任何文本模式。它们非常有用。因此,即使您现在可以坚持从另一个答案复制粘贴代码 sn-p,您也应该考虑深入研究一下。
一开始可能有点复杂,但绝对值得努力。
【讨论】:
【参考方案12】:我还修改了@Rob Locke 的答案。我发现它对我不起作用,因为我必须先用逗号分隔,然后再用空格分隔。
function extract_email_addresses($sString)
$aRet = array();
$aCsvs = explode(',', $sString);
foreach($aCsvs as $sCsv)
$aWords = explode(' ', $sCsv);
foreach($aWords as $sWord)
$sEmail = filter_var(filter_var($sWord, FILTER_SANITIZE_EMAIL), FILTER_VALIDATE_EMAIL);
if($sEmail !== false)
$aRet[] = $sEmail;
return $aRet;
【讨论】:
【参考方案13】:匹配正则表达式,例如 - ([A-Za-z0-9-]+)@([A-Za-z0-9])\\.([a-z]3)
或类似的东西。
【讨论】:
【参考方案14】:以下解决方案是https://***.com/a/47150078/3010827的修改版,更容易理解
$text = 'First Last <name@example.com>';
// split the string into multiple parts base on a space separator
$parts = preg_split('/\s/', $text);
// Sanitize each part by removing invalid email characters. For example <joe.doe@email.com> will become joe.doe@email.com
$parts = filter_var_array($parts, FILTER_SANITIZE_EMAIL);
// Filter out invalid emails for each part. Valid emails will be kept while invalid ones will be replaced by `false`
$emails = filter_var_array($parts, FILTER_VALIDATE_EMAIL);
// remove `false` values from the array of emails, that's the default behavior of array_filter without the optional callback function
$emails = array_filter($emails);
【讨论】:
以上是关于如何从长字符串中获取电子邮件地址的主要内容,如果未能解决你的问题,请参考以下文章