PHP разделяет строку писем с запятыми в именах иногда

У меня есть старые данные, которые содержат адреса электронной почты в строках, например так:

$str = 'Joe Bloggs <[email protected]>, Person, Test [[email protected]], [email protected]'

Я хотел бы разбить эту строку на 3 электронных письма, содержащихся внутри, но вы можете видеть, что некоторые имена содержат разделитель запятых, а некоторые электронные письма не имеют названия спецификации RFC в начале. В идеале строка выше должна быть разбита на следующий массив:

Array (
[0] => Array(
'name' => 'Joe Blogs',
'email' => '[email protected]'
)
[1] => Array(
'name' => 'Person, Test',
'email' => '[email protected]'
),
[2] => Array(
'name' => '',
'email' => '[email protected]'
)
)

Я предполагаю, что регулярное выражение будет работать здесь? Я придумал следующее, но он обрабатывает только один адрес электронной почты, а не список через запятую (также с запятыми в имени!):

preg_match_all('!(.*?)\s?[<|\[]\s*(.*?)\s*[>|\]]!',$string,$matches);

Спасибо!

1

Решение

Вы можете использовать

(?:,\s*)?(.*?)\s*(?|<([^>]*)>|\[([^][]*)]|(\S+@\S+))

Увидеть regex demo

подробности

  • (?:,\s*)? — необязательная последовательность , а затем 0+ пробелов
  • (.*?) — Группа 1 (имя): любые 0+ символов, кроме символов разрыва строки, как можно меньше
  • \s* — 0+ пробелов
  • (?|<([^>]*)>|\[([^][]*)]|(\S+@\S+)) — соответствие группы сброса ветви
    • <([^>]*)>|<, тогда любые 0+ символов кроме > захвачены в группе 1 и > просто соответствует
    • \[([^][]*)]|[, тогда любые 0+ символов кроме ] захвачены в группе 1 и ] просто соответствует
    • (\S+@\S+) — 1 или более непробельных символов, @и снова 1+ непробельные символы фиксируются в группе 1.

А потом использовать следующий код PHP Для получения необходимых результатов:

$re = '/(?:,\s*)?(.*?)\s*(?|<([^>]*)>|\[([^][]*)]|(\S+@\S+))/';
$str = 'Joe Bloggs <[email protected]>, Person, Test [[email protected]], [email protected]';
preg_match_all($re, $str, $m, PREG_SET_ORDER, 0);
$res = array();
foreach ($m as $e)
{
$res[] = array('name' => $e[1], 'address' => $e[2]);
}
print_r($res);

Выход:

Array
(
[0] => Array
(
[name] => Joe Bloggs
[address] => [email protected]
)

[1] => Array
(
[name] => Person, Test
[address] => [email protected]
)

[2] => Array
(
[name] =>
[address] => [email protected]
)

)
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]