从字符串中检索完整的电子邮件地址
Posted
技术标签:
【中文标题】从字符串中检索完整的电子邮件地址【英文标题】:Retrieve full email address from string 【发布时间】:2017-04-03 04:47:17 【问题描述】:我目前正在使用 Laravel 构建一个 Slack 机器人,其中一个功能是它可以接收电子邮件地址并向其发送消息。
问题是电子邮件地址(例如 bob@example.com
)来自 Slack 的 <mailto:bob@example.com|bob@example.com>
。
我目前有一个从中检索电子邮件的功能:
public function getEmail($string)
$pattern = '/[a-z0-9_\-\+]+@[a-z0-9\-]+\.([a-z]2,3)(?:\.[a-z]2)?/i';
preg_match_all($pattern, $string, $matches);
$matches = array_filter($matches);
return $matches[0][0];
这似乎适用于bob@example.com
之类的电子邮件地址,但是在使用bob.jones@example.com
之类的电子邮件地址时它似乎失败了(它会以<mailto:bob.jones@example.com|bob.jones@example.com>
出现。
在这些情况下,函数返回jones@example.com
作为电子邮件地址。
我不擅长正则表达式,但我可以在我的模式中使用/更改其他东西,或者从 Slack 提供的字符串中获取电子邮件地址的更好方法吗?
【问题讨论】:
如果str总是这样,也可以试试preg_match('/mailto:\K[^|>]+/', $str, $out)
。
【参考方案1】:
如果您知道正则表达式始终是它的格式,那么总是可以将其排除在等式之外:
$testString = '<mailto:bob@example.com|bob@example.com>';
$testString = str_replace(['<mailto:', '>'], '', $testString);
$addresses = explode('|', $testString);
echo $addresses[0];
【讨论】:
只需添加以下内容进行验证:foreach ($addresses as $value) if (filter_var($value, FILTER_VALIDATE_EMAIL)) echo "Valid Email: " . $value . "<br>";
这与@Kitson88 的一个小调整相结合,效果很好。谢谢你们!
@bcmcfc,看来你是 laravel 大师了。我需要你帮忙。看这里:***.com/questions/41887504/…【参考方案2】:
这种方法可以完成这项工作,您可以避免使用正则表达式。并确保返回的电子邮件是一个真实的电子邮件地址,方法是使用 php 函数对其进行验证。
function getEmailAddress($string)
$string = trim($string, '<>');
$args = explode('|', $string);
foreach ($args as $_ => $val)
if(filter_var($val, FILTER_VALIDATE_EMAIL) !== false)
return $val;
return null;
echo getEmailAddress('<mailto:bob@example.com|bob@example.com>');
输出
bob@example.com
【讨论】:
【参考方案3】:您知道包含电子邮件地址的字符串将始终采用<mailto:bob@example.com|bob@example.com>
的形式,因此请使用它。具体来说,您知道字符串将以<mailto:
开头,包含|
,并以>
结尾。
另外一个困难是,电子邮件地址的本地部分也可能包含管道字符,但域可能不包含;请参阅以下问题。What characters are allowed in an email address?
public function getEmail($string)
$pattern = '/^<mailto:([^@]+@[^|]+)|(.*)>$/i';
preg_match_all($pattern, $string, $matches);
$matches = array_filter($matches);
return $matches[1][0];
这匹配从头到尾的整行,但我们在第一组括号内捕获电子邮件地址。 $matches[1]
包含第一个捕获括号中的所有匹配项。您可以改用preg_match
,因为您不是在查找所有匹配项,而是查找第一个匹配项。
【讨论】:
+1 从来不知道电子邮件可以包含管道。虽然看起来很疯狂,想象一下试图通过电话向某人解释您的电子邮件具有管道字符。有时让人们理解个人领域已经够难的了!出于好奇,我刚刚测试了 gmail,他们只支持规范的一个子集:“请仅使用字母 (a-z)、数字和句点。” @bcmcfc 每个域都可以设置自己的规则,只要它们不违反规范。但他们不必实施完整的规范。换句话说,GMail 不必允许bc|mc|fc@gmail.com
,但他们应该允许向bc|mc|fc$@someotherdomain.com
发送电子邮件。
@SQB,看来你掌握了 laravel。我需要你帮忙。看这里:***.com/questions/41047583/…以上是关于从字符串中检索完整的电子邮件地址的主要内容,如果未能解决你的问题,请参考以下文章