大量的文本,樱桃挑选电子邮件地址

时间:2010-02-25 15:23:34

标签: php regex

我有一个充满文字的大文件,并且有一些电子邮件地址。

哪个php正则表达式函数会返回它可以找到的电子邮件地址数组?

到目前为止我已经

<?php

$pattern = "/^[^@]*@[^@]*\.[^@]*$/";

if ($handle = opendir('files')) {

/* This is the correct way to loop over the directory. */
while (false !== ($file = readdir($handle))) {
   preg_match($pattern, $file, $matches);

   echo count($matches);
   foreach ($matches as $email) {
     echo "$email <br />";
   }
}

closedir($handle);
}

但它没有返回结果

7 个答案:

答案 0 :(得分:3)

值得注意的是,在谷歌搜索正则表达式后,使用我的脚本,这里是我收集的模式:

    $pattern = "^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$";
$pattern = "/([\s]*)([_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*([ ]+|)@([ ]+|)([a-zA-Z0-9-]+\.)+([a-zA-Z]{2,}))([\s]*)/i";
$pattern = '#([^@]+@[-a-z0-9.]+)#';
$pattern = '(^|\s|<)[a-zA-Z]([.+-]?\w+)+@(\w{2,}\.)+\w{2,5}($|\s|>)';
$pattern = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$";
$pattern = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?";
$pattern = "(^|\s|<)[a-zA-Z]([.+-]?\w+)+@(\w{2,}\.)+\w{2,5}($|\s|>)";

最好的模式是:

$pattern = "/([\s]*)([_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*([ ]+|)@([ ]+|)([a-zA-Z0-9-]+\.)+([a-zA-Z]{2,}))([\s]*)/i";

答案 1 :(得分:1)

尝试类似:

$file = file_get_contents('filename.txt');
if(preg_match_all('#([^@]+@[-a-z0-9.]+)#',$file,$matches)) {
  $emails = $matches[1]; // array of all the emails in the file.
}

正则表达式已经简化,而不是100%RFC822实现。

修改

readdir函数在成功时返回文件名而不是文件内容。您可以尝试:

while (false !== ($file = readdir($handle))) {
   $file_contents = file_get_contents($file);
   if(preg_match_all('#([^@]+@[-a-z0-9.]+)#', $file_content, $matches)) {

     echo count($matches[1]);
     foreach ($matches[1] as $email) {
       echo "$email <br />";
   }
}

答案 2 :(得分:1)

我看到三个问题:

  1. 在正则表达式中,^表示行(或字符串)的开头,$表示行(或字符串)的结尾,这可能就是为什么你的模式使用不起作用。它只会在一行上找到一个电子邮件地址。

  2. 您正在将文件名称传递给preg_match;期待搜索一个字符串。您需要调用file_get_contents或类似的内容将文件的文本传递给函数。

  3. 如果每个文件中有多个地址,则需要使用preg_match_all一次查找多个匹配项。

答案 3 :(得分:0)

通读

你可以调整那里给出的正则表达式或者你可以在网上找到的任何其他正则表达式,然后只需做一个

preg_match_all($pattern, $someString, $matches);
然后

$matches将包含您使用的正则表达式所找到的任何内容。

如果您的文件太大而无法加载到内存中,请考虑使用fgets()进行迭代。

答案 4 :(得分:0)

有很多网站都在讨论电子邮件地址的正则表达式。 This one特别是非常广泛。

简短的回答是,“有效”电子邮件地址的定义不适用于简单的正则表达式。电子邮件地址的大多数实用正则表达式都是为了简单起见而交换完整性。

答案 5 :(得分:0)

最终代码,完美无缺,谢谢大家:)

<?php

set_time_limit('0');
$pattern = "^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$";

if ($handle = opendir('files')) {
    while (false !== ($file = readdir($handle))) {
        $content = file_get_contents('files/'.$file);
        preg_match_all('#([^@]+@[-a-z0-9.]+)#', $content, $matches);
        echo count($matches[1]).' - '.$file.'<br />';
    }
    closedir($handle);
}

答案 6 :(得分:0)

试试这个:

(^|\s|<)[a-zA-Z]([.+-]?\w+)+@(\w{2,}\.)+\w{2,5}($|\s|>)

将其他可能的分隔符添加到起始和结束组^|\s|<