域名的唯一电子邮件地址

时间:2012-06-19 09:22:54

标签: php

我试图使下面的功能只返回每个域1个电子邮件。

示例:如果我提供功能:

  

email1@domain.com email2@domain.com email1@domain.com   email1@domain.com email3@test.co.uk

我希望它返回

  

email1@domain.com email3@test.co.uk

这是当前的功能:

function remove_duplicates($str) {

  # match all email addresses using a regular expression and store them
  # in an array called $results
  preg_match_all("([\w-]+(?:\.[\w-]+)*@(?:[\w-]+\.)+[a-zA-Z]{2,7})",$str,$results);

  # sort the results alphabetically
  sort($results[0]);

  # remove duplicate results by comparing it to the previous value
  $prev="";
  while(list($key,$val)=each($results[0])) {
    if($val==$prev) unset($results[0][$key]);
    else $prev=$val;
  }

  # process the array and return the remaining email addresses
  $str = "";
  foreach ($results[0] as $value) {
     $str .= "<br />".$value;
  }

  return $str;
};

任何想法如何实现这一目标?

4 个答案:

答案 0 :(得分:2)

这些方面的东西:

$emails = array('email1@domain.com', 'email2@domain.com', 'email1@domain.com', 'email1@domain.com', 'email3@test.co.uk');

$grouped = array();
foreach ($emails as $email) {
    preg_match('/(?<=@)[^@]+$/', $email, $match);
    $grouped[$match[0]] = $email;
}

var_dump($grouped);

这可以保持域的最后次出现,如果您需要,可以不修改以保留第一个

答案 1 :(得分:1)

您只需使用array_unique功能为您完成工作:

$emails = explode(' ', $emailString);
$emails = array_unique($emails);

答案 2 :(得分:0)

概念prev不可靠,除非所有相同的主机名都在一个连续的序列中。如果您按主机名排序,并提供排序功能,它会起作用,但这有点过分。

使用主机名构建一个数组,删除数组中已有主机名的条目。

答案 3 :(得分:0)

我建议采用以下技巧/程序:

  1. 从一个字符串更改为地址数组。您使用preg_match_all执行此操作,其他人可能会使用explode执行此操作,所有内容似乎都有效。所以你已经有了这个。
  2. 从地址中提取域名。你可以用正则表达式或其他东西再次这样做,我会说这很简单。
  3. 现在检查域是否已被使用,如果没有,请选择该电子邮件地址。
  4. 通过使用数组和域作为键,可以轻松完成最后一点。然后,您可以使用isset查看它是否已在使用中。

    编辑:由于deceze选择了类似的答案(他会覆盖每个域的匹配),下面的代码示例有点变化。由于你有字符串输入,我考虑逐步迭代它以备用临时的地址数组,并立即进行地址和域解析。为此,您需要处理preg_match支持的偏移量。 preg_match_all实际上可能有类似的东西,但是你会再次拥有该数组。

    此代码将选择第一个并忽略每个域的其他地址:

    $str = 'email1@domain.com email2@domain.com email1@domain.com email1@domain.com email3@test.co.uk';
    $addresses = array();
    $pattern = '/[\w-]+(?:\.[\w-]+)*@((?:[\w-]+\.)+[a-zA-Z]{2,7})/';
    $offset = 0;
    while (preg_match($pattern, $str, $matches, PREG_OFFSET_CAPTURE, $offset)) {
        list(list($address, $pos), list($domain)) = $matches;
        isset($addresses[$domain]) || $addresses[$domain] = $address;
        $offset = $pos + strlen($address);
    }