0

以下の関数を作成しようとすると、ドメインごとに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

4 に答える 4

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);

これにより、ドメインの最後のオカレンスが保持されます。必要に応じて、代わりに最初のドメインを保持するように変更することは難しくありません。

于 2012-06-19T09:28:29.967 に答える
1

関数を使用して、array_uniqueあなたのために仕事をすることができます:

$emails = explode(' ', $emailString);
$emails = array_unique($emails);
于 2012-06-19T09:25:34.677 に答える
0

prevすべての等しいホスト名が 1 つの連続したシーケンスに含まれていない限り、この概念は信頼できません。ホスト名でソートし、ソート機能が提供されていれば機能しますが、少しやり過ぎです。

ホスト名で配列を構築し、配列に既にホスト名があるエントリを削除します。

于 2012-06-19T09:26:52.927 に答える
0

次のトリック/手順をお勧めします。

  1. 1 つの文字列からアドレスの配列に変更します。あなたは でこれを行いpreg_match_all、他の人は で行うかもしれませんがexplode、すべて有効に見えます。だから、あなたはすでにこれを持っています。
  2. アドレスからドメインを抽出します。正規表現などを使用してこれをもう一度行うことができますが、それは些細なことだと思います。
  3. ドメインが既に使用されているかどうかを確認し、使用されていない場合はそのメール アドレスを選択します。

最後のポイントは、配列とドメインをキーとして使用することで簡単に実行できます。その後、 を使用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);
}
于 2012-06-19T09:30:54.953 に答える