Получить полный адрес электронной почты из строки


В настоящее время я создаю бота Slack с использованием Laravel, и одна из особенностей заключается в том, что он может получать адрес электронной почты и отправлять на него сообщения.

Проблема в том, что адреса электронной почты (например, [email protected]) поступают как <mailto:[email protected]|[email protected]> из Slack.

В настоящее время у меня есть функция, которая извлекает электронное письмо из этого:

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

Казалось, что это нормально работает с адресами электронной почты, такими как [email protected], однако, похоже, это не работает при работе с адресами электронной почты, такими как [email protected] (которые будут проходить как <mailto:[email protected]|[email protected]>. В этих случаях функция возвращает [email protected] в качестве адреса электронной почты.

Я не очень хорошо разбираюсь в регулярных выражениях, но есть ли что-то еще, что я мог бы использовать/изменить в своем шаблоне, или лучший способ получить адрес электронной почты из строки, предоставленной Slack?

Author: Kurt Van den Branden, 2016-11-19

3 answers

Всегда можно исключить регулярное выражение из уравнения, если вы знаете, что оно всегда будет в таком формате:

$testString = '<mailto:[email protected]|[email protected]>';

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

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

echo $addresses[0];
 10
Author: bcmcfc, 2016-11-19 11:25:27

Этот метод выполнит свою работу, и вы избежите использования регулярных выражений. и убедитесь, что возвращаемое электронное письмо является реальным адресом электронной почты, проверив его с помощью функций 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:[email protected]|[email protected]>');

Выход

[email protected]
 4
Author: jycr753, 2016-11-19 11:51:09

Вы знаете, что строки, содержащие адрес электронной почты, всегда будут иметь вид <mailto:[email protected]|[email protected]>, поэтому используйте это. В частности, вы знаете, что строка будет начинаться с <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, так как вы ищете не все совпадения, а только первое.

 0
Author: SQB, 2017-05-23 12:32:02