简体   繁体   English

从字符串中检索完整的电子邮件地址

[英]Retrieve full email address from string

I'm currently building a Slack bot using Laravel, and one of the features is that it can receive an email address and send a message to it. 我目前正在使用Laravel构建Slack机器人,其中一个功能是它可以接收电子邮件地址并向其发送消息。

The issue is that email addresses (eg bob@example.com ) come through as <mailto:bob@example.com|bob@example.com> from Slack. 问题是电子邮件地址(例如bob@example.com )来自Slack的<mailto:bob@example.com|bob@example.com>

I currently have a function that retrieves the email from this: 我目前有一个函数可以从中检索电子邮件:

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];
}

This seemed to be working fine with email addresses like bob@example.com , however it seems to fail when working with email addresses like bob.jones@example.com (which would come through as <mailto:bob.jones@example.com|bob.jones@example.com> . In these cases, the function is returning jones@example.com as the email address. 这似乎适用于bob@example.com这样的电子邮件地址,但是在使用bob.jones@example.com这样的电子邮件地址时似乎失败了(这可以通过<mailto:bob.jones@example.com|bob.jones@example.com> 。在这些情况下,该函数返回jones@example.com作为电子邮件地址。

I'm not great with regex, but is there something else I could use/change in my pattern, or a better way to fetch the email address from the string provided by Slack? 我对正则表达式不是很好,但是我可以使用/改变我的模式,还是从Slack提供的字符串中获取电子邮件地址的更好方法?

Could always take regex out of the equation if you know that's always the format it'll be in: 如果您知道它始终是它的格式,那么总是可以将正则表达式从等式中取出:

$testString = '<mailto:bob@example.com|bob@example.com>';

$testString = str_replace(['<mailto:', '>'], '', $testString);

$addresses = explode('|', $testString);

echo $addresses[0];

This method will do the job and you avoid to have regular expressions. 这个方法可以完成这项工作,你可以避免使用正则表达式。 and make sure the email being returned is a real email address by validating it with php functions. 并通过使用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>');

Output 产量

bob@example.com

You know the strings containing the e-mail address will always be of the form <mailto:bob@example.com|bob@example.com> , so use that. 您知道包含电子邮件地址的字符串将始终采用<mailto:bob@example.com|bob@example.com> ,因此请使用它。 Specifically, you know the string will start with <mailto: , will contain a | 具体来说,你知道字符串将以<mailto:开头,将包含一个| , and will end with > . ,并将以>结束。

An added difficulty though, is that the local part of an e-mail address may contain a pipe character as well, but the domain may not; 但是,另一个困难是,电子邮件地址的本地部分也可能包含管道字符,但域名可能不包含; see the following question. 看到以下问题。
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];
}

This matches the full line from beginning to end, but we capture the e-mail address within the first set of parentheses. 这从开始到结束匹配整行,但我们捕获第一组括号内的电子邮件地址。 $matches[1] contains all matches from the first capturing parentheses. $matches[1]包含第一个捕获括号的所有匹配项。 You could use preg_match instead, since you're not looking for all matches, just the first one. 您可以使用preg_match ,因为您不是在寻找所有匹配项,而只是第一个匹配项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM