2010-07-27 15 views
0

Considérez le script suivant qui contient des adresses e-mail masquées et une fonction qui tente de les remplacer par ***** en utilisant la correspondance de modèle regex. Mon script tente d'attraper les mots: "at", "a t", "a.t", "@" suivi d'un peu de texte (n'importe quel nom de domaine), suivi de "dot" "." "d.o.t", suivi d'un TLD.Comment puis-je attraper les adresses email obfusquées suivantes en PHP?

entrée:

$str[] = 'dsfatasdfasdf asd dsfasdf [email protected]'; 
$str[] = 'I live at school where My address is [email protected]'; 
$str[] = 'I live at school. My address is [email protected]'; 
$str[] = 'at school my address is [email protected]'; 
$str[] = 'dsf a t asdfasdf asd dsfasdf [email protected]'; 
$str[] = 'd s f d s f a t h o t m a i l . c o m'; 

function clean_text($text){ 
    $pattern = '/(\ba[ \.\-_]*t\b|@)[ \.\-_]*(.+)[ \.\-_]*(d[ \.\-_]*o[ \.\-_]*t|\.)[ \.\-_]*(c[ \.\-_]*o[ \.\-_]*m|n[ \.\-_]*e[ \.\-_]*t|o[ \.\-_]*r[ \.\-_]*g|([a-z][ \.\-_]*){2,3}[a-z]?)/iU'; 
    return preg_replace($pattern, '***', $text); 
} 

foreach($str as $email){ 
    echo clean_text($email); 
} 

Résultats attendus:

dsfatasdfasdf asd dsfasdf dsfdsf*** 
I live at school where My address is [email protected]*** 
I live at school. My address is [email protected]*** 
*** 
dsf *** 
d s f d s f *** 

Résultat:

dsfatasdfasdf asd dsfasdf dsfdsf*** 
I live *** 
I live *** 
at school my address is dsfdsf**** 
dsf *** 
d s f d s f *** 

Problème: Il attrape la première occurrence de « à », et non le dernier, donc ce qui suit se produit:

input: 'at school my address is [email protected]' 
produces: '****' 
should produce: 'at school my address is dsfdsf****' 

Comment puis-je résoudre ce problème?

+3

je suppose la question évidente est pourquoi les adresses sont obscurcies? Si c'est délibérément par les utilisateurs, alors n'importe quel arrangement que vous venez avec sera travaillé autour. –

+0

@ Douglas, c'est bien. Même s'ils travaillent autour de ça, j'aimerais quand même les décourager. –

+0

Essayer d'analyser le langage naturel avec regexp n'est pas la meilleure idée, car il y a tellement de nuance que tout ce que vous essayez de construire avec regexp est cassé. C'est comme essayer d'analyser HTML avec regexp. – HoLyVieR

Répondre

2

Basé sur regex M42:

code:

$emails = array(
       'dsfatasdfasdf asd dsfasdf [email protected]' 
       ,'I live at school where My address is [email protected]' 
       ,'I live at school. My address is [email protected]' 
       ,'at school my address is [email protected]' 
       ,'dsf a t asdfasdf asd dsfasdf [email protected]' 
       ,'d s f d s f a t h o t m a i l . c o m' 
       ); 

foreach($emails as $email) 
{ 
    $found = preg_match('/(.*?)((\@|a[_. -]*t)[\w .-]*?$)/', $email, $matches); 
    if($found) 
    { 
     echo 'Username: ' . $matches[1] . ', Domain: ' . $matches[2] . "\n"; 
    } 
} 

Sortie:

Username: dsfatasdfasdf asd dsfasdf dsfdsf, Domain: @hotmail.com 
Username: I live at school where My address is dsfdsf, Domain: @hotmail.com 
Username: I live at school. My address is dsfdsf, Domain: @hotmail.com 
Username: at school my address is dsfdsf, Domain: @hotmail.com 
Username: dsf a t asdfasdf asd dsfasdf dsfdsf, Domain: @hotmail.com 
Username: d s f d s f , Domain: a t h o t m a i l . c o m 
0
function clean_text($text){ 
    $pattern = '/\w+[\w-\.]*(\@\w+((-\w+)|(\w*))\.[a-z]{2,3})/i'; 
    preg_match($pattern, $text, $matches); 

    return (isset($matches[1])) ? str_replace($matches[1], "****", $text) : $text; 
} 

Le seul qui ne correspond pas est le dernier, mais vous obtenez le point.

+0

C'est très bien, mais je dois spécifiquement attraper le cas "at", et en général le cas "a t" (a, any non-aplhanum, t). Merci pour l'effort jusqu'à présent. –

+0

Le point cependant n'est pas d'utiliser un preg_replace droit mais réellement preg_match et ensuite remplacer par l'index de la correspondance pour la deuxième partie de l'email. Cela devrait au moins vous aider à aller dans la bonne direction. – cynicaljoy

1

Ce script Perl, pourrait être adapté à php?

my @l = (
'dsfatasdfasdf asd dsfasdf [email protected]', 
'I live at school where My address is [email protected]', 
'I live at school. My address is [email protected]', 
'at school my address is [email protected]', 
'dsf a t asdfasdf asd dsfasdf [email protected]', 
'd s f d s f a t h o t m a i l . c o m' 
); 

foreach(@l) { 
    s/(\@|a[_. -]*t)[\w .-]*?$/****/; 
    print $_,"\n"; 
} 

sortie:

dsfatasdfasdf asd dsfasdf dsfdsf**** 
I live at school where My address is dsfdsf**** 
I live at school. My address is dsfdsf**** 
at school my address is dsfdsf**** 
dsf a t asdfasdf asd dsfasdf dsfdsf**** 
d s f d s f ****