Misa de texto, direcciones de correo electrónico selectas

Tengo un archivo grande lleno de texto y hay algunas direcciones de correo electrónico.

¿Qué función de expresión regular php devolvería una matriz de direcciones de correo electrónico que podría encontrar?

Hasta ahora tengo

<?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 
"; } } closedir($handle); }

pero no devuelve resultados

Digno de mención, después de buscar google para regex, con mi script, aquí están los patrones que recolecté:

  $pattern = "^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[az]{2,4})$"; $pattern = "/([\s]*)([_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*([ ]+|)@([ ]+|)([a-zA-Z0-9-]+\.)+([a-zA-Z]{2,}))([\s]*)/i"; $pattern = '#([^@][email protected][-a-z0-9.]+)#'; $pattern = '(^|\s|<)[a-zA-Z]([.+-]?\w+)[email protected](\w{2,}\.)+\w{2,5}($|\s|>)'; $pattern = "^[a-zA-Z0-9_.-][email protected][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+)[email protected](\w{2,}\.)+\w{2,5}($|\s|>)"; 

El mejor patrón es:

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

Veo tres problemas:

  1. En expresiones regulares, ^ significa el inicio de una línea (o cadena) y $ significa el final de una línea (o cadena), esa es probablemente la razón por la que el patrón que está utilizando no funciona. Solo encontraría una dirección de correo electrónico en una línea sola.

  2. Está pasando el nombre del archivo a preg_match ; está esperando que se busque una cadena. Necesitas llamar a file_get_contents o algo similar para pasar el texto del archivo a la función.

  3. preg_match_all usar preg_match_all para buscar más de una coincidencia a la vez, si hay varias direcciones en cada archivo.

Pruebe algo como:

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

La expresión regular se simplifica y no es una implementación 100% RFC822.

EDITAR:

La función readdir devuelve el nombre del archivo en caso de éxito, no el contenido del archivo. Puedes intentar hacer:

 while (false !== ($file = readdir($handle))) { $file_contents = file_get_contents($file); if(preg_match_all('#([^@][email protected][-a-z0-9.]+)#', $file_content, $matches)) { echo count($matches[1]); foreach ($matches[1] as $email) { echo "$email 
"; } }

Leer de parte a parte

  • Usar una expresión regular para validar una dirección de correo electrónico

Puede adaptar la Regex dada allí o cualquier otra Regex que pueda encontrar en la web para este fin y luego simplemente hacer una

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

$matches contendrá lo que se encontró para la Regex que usaste.

En caso de que su archivo sea demasiado grande para ser cargado en la memoria, considere iterar sobre él con fgets () .

Hay una serie de sitios que hablan de expresiones regulares para direcciones de correo electrónico. Este en particular es bastante expansivo.

La respuesta corta es que la definición de una dirección de correo electrónico “válida” no se presta para una expresión regular simple. La mayoría de las expresiones regulares prácticas para direcciones de correo electrónico se completan para mayor simplicidad.

Código final, que funciona perfecto, gracias a todos 🙂

 '; } closedir($handle); } 

Prueba este:

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

Agregue otros delimitadores posibles a los grupos inicial y final ^|\s|<