2013-09-04 7 views
0

Je suis triyng pour extraire un peu d'url, il peut y en avoir plus d'un, qui viennent dans un courriel de corps.Comment extraire href d'un courriel de corps, en Perl?

Et je suis en train d'analyser les urls, avec ceci:

use strict; 
use warnings; 
use Net::IMAP::Simple; 
use Email::Simple; 
use IO::Socket::SSL; 

# here must be the connection to imap hidden for economize space 

my $es = Email::Simple->new(join '', @{ $imap->get($i) }); 
my $text = $es->body; 
print $text; 
my $matches = ($text =~/<a[^>]*href="([^"]*)"[^>]*>.*<\/a>/); 
print $matches; 

Le texte $ i ont le prochain texte:

--047d7b47229eb3d9f404e58fd90a 
    Content-Type: text/plain; charset=ISO-8859-1 

    Try1 <http://www.washingtonpost.com/> 

    Try2 <http://www.thesun.co.uk/sol/homepage/> 

    --047d7b47229eb3d9f404e58fd90a 
    Content-Type: text/html; charset=ISO-8859-1 

    <div dir="ltr"><a href="http://www.washingtonpost.com/">Try1</a><br><div><br></div><div><a href="http://www.thesun.co.uk/sol/homepage/">Try2</a><br></div></div> 

    --047d7b47229eb3d9f404e58fd90a-- 

La sortie du programme, me donne un 1 ... juste ça.

Quelqu'un peut-il aider ??

Merci dans le conseil.

+3

[* Ne pas * HTML parse avec regexp] (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454# 1732454). – Carsten

+0

Ce module est inutile si c'est ce qu'il vous donne pour le corps. – ikegami

+1

** N'utilisez pas d'expressions régulières pour analyser HTML. Utilisez un module d'analyse syntaxique HTML approprié. ** Vous ne pouvez pas analyser le code HTML de manière fiable avec des expressions régulières, et vous serez confronté à la tristesse et à la frustration sur la route. Dès que le HTML change de vos attentes, votre code sera brisé. Voir http://htmlparsing.com/php ou [ce thread SO] (http://stackoverflow.com/questions/3577641/how-do-you-parse-and-process-html-xml-in-php) pour des exemples de comment analyser correctement HTML avec des modules PHP qui ont déjà été écrits, testés et débogués. –

Répondre

6

Email :: Simple n'est pas adapté aux messages MIME. Utilisez Courriel à la place. Regex ne sont pas adaptés à l'analyse HTML. Utilisez Web::Query à la place.

use Courriel qw(); 
use Web::Query qw(); 

my $email = Courriel->parse(text => join …); 
my $html = $email->html_body_part; 
my @url = Web::Query->new_from_html($html)->find('a[href]')->attr('href'); 
__END__ 
http://www.washingtonpost.com/ 
http://www.thesun.co.uk/sol/homepage/ 
+0

Courriel n'est pas disponible sur winx64 .. il semble bien réparé .. mais ne peut pas l'utiliser dès maintenant. – snnifer

+0

En ce moment, en utilisant la requête Web sans courriel, résolvez le problème. Merci – snnifer

2

Les conseils que vous avez reçu sur l'utilisation d'un autre module de traitement de courrier électronique et non l'analyse syntaxique HTML avec des expressions régulières est tout bon et vous devez tenir compte certainement.

Mais personne n'a encore expliqué pourquoi votre code vous donne des résultats incorrects. C'est parce que vous appelez l'opérateur de correspondance dans un contexte scalaire. Dans le contexte scalaire, il renvoie une valeur booléenne indiquant si la correspondance a réussi ou non. D'où le 1 (vrai) que vous obtenez. Pour obtenir les captures de la regex, vous devez appeler l'opérateur match dans le contexte de la liste. Cela pourrait être aussi simple que cela:

my ($matches) = ($text =~/<a[^>]*href="([^"]*)"[^>]*>.*<\/a>/); 

Mais vous pouvez envisager d'utiliser un tableau si vous voulez toujours ajouter/g à l'opérateur de correspondance et obtenir plusieurs matchs.

my @matches = ($text =~/<a[^>]*href="([^"]*)"[^>]*>.*<\/a>/g); 
+0

en essayant cela, mais quand j'imprime @matches, il suffit d'obtenir l'une des URL. En ce moment, ne sais pas si l'autre URL est sur les allumettes variable ou non ... – snnifer

+0

Travailler sans regexp, bien que l'expression rationnelle juste choisir l'une des urls – snnifer

+0

Yep. C'est le problème avec l'analyse de HTML avec des regex. C'est toujours plus dur que tu ne le penses. Où vous avez '>. * <\/a>' vous devez le changer pour '>. *? <\/a> '. Travailler sur pourquoi est laissé comme un exercice pour le lecteur :-) –

Questions connexes