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

我目前正在使用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提供的字符串中获取电子邮件地址的更好方法?


如果你知道它始终是它的格式,那么总是可以将正则表达式排除在外:

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

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

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

echo $addresses[0];

这种方法将完成这项工作,并避免使用正则表达式。 并确保所返回的电子邮件是一个真正的电子邮件地址,通过验证它的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

您知道包含电子邮件地址的字符串将始终为<mailto:bob@example.com|bob@example.com>的格式,因此请使用它。 具体来说,您知道该字符串将以<mailto:开头,将包含| ,并以>结尾。

然而,另一个困难是,电子邮件地址的本地部分也可能包含管道字符,但该域名可能不会; 看到下面的问题。
电子邮件地址允许使用哪些字符?

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 ,因为您不是在寻找所有匹配,只是第一个匹配。

链接地址: http://www.djcxy.com/p/92873.html

上一篇: Retrieve full email address from string

下一篇: Should uppercase letters be allowed in email addresses?