2010-03-20 4 views
2

J'ai une chaîne de texte qui contient html, et j'ai besoin d'extraire chaque URL (probablement dans img ou une balise) pour créer une liste générique d'objets chaîne. Je veux seulement les URL de l'intérieur des balises html, pas dans le texte. Existe-t-il un moyen facile de le faire ou devrais-je recourir à des expressions régulières?extrait toutes les URL d'une chaîne

Si je dois recourir à des expressions régulières, cela vous dérangerait-il de m'aider aussi? :)

MISE À JOUR: Pour répondre à Seph, l'entrée sera standard html.

<p>This is some html text. my favourite website is <a href="http://www.google.com">google</a> and my favourite help site is <a href="http://www.stackoverflow.com">stackoverflow</a> and i check my email at <a href="http://www.gmail.com">gmail</a>. the url to my site is http://www.mysite.com. <img src="http://www.someserver.com/someimage.jpg" alt=""/></p> 

Je veux

le résultat final devrait être dans tous les urls tout html étiquette, ignorant ceux-ci sont sont « texte brut »

UPPERDATE Bien qu'il ait supprimé sa réponse, je tiens à remercier Jerry Bullard d'avoir attiré mon attention Regex amis (http://www.regexbuddy). Je voulais mettre en doute votre réponse, mais il est parti. Ramenez-le et vous aurez un vote!

+0

Un texte serait utile, avec la sortie exacte désirée. – Seph

+0

merci, voir ci-dessus –

+0

@ codemonkey12: voir ma mise à jour basée sur votre commentaire RegexBuddy. –

Répondre

1

Quelque chose comme cela devrait aider:

private List<string> GetUrlStrings(string text) 
    { 
     List<string> listURL = new List<string>(); 
     Regex regex = new Regex("href\\s*=\\s*(?:(?:\\\"(?<url>[^\\\"]*)\\\")|(?<url>[^\\s]*))"); 
     MatchCollection mathColl = regex.Matches(text); 

     foreach (Match match in mathColl) 
     { 
      foreach (Group group in match.Groups) 
      { 
       if (!group.Value.StartsWith("href")) // workaround regex issue 
       { 
        listURL.Add(group.Value); 
       } 
      } 
     } 
     return listURL; 
    } 
-1

Ce code peut être d'une certaine aide :) Tiré de http://www.vogella.de/articles/JavaRegularExpressions/article.html.

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class LinkGetter { 
    private Pattern htmltag; 
    private Pattern link; 
    private final String root; 

    public LinkGetter(String root) { 
     this.root = root; 
     htmltag = Pattern.compile("<a\\b[^>]*href=\"[^>]*>(.*?)</a>"); 
     link = Pattern.compile("href=\"[^>]*\">"); 
    } 

    public List<String> getLinks(String url) { 
     List<String> links = new ArrayList<String>(); 
     try { 
      BufferedReader bufferedReader = new BufferedReader(
        new InputStreamReader(new URL(url).openStream())); 
      String s; 
      StringBuilder builder = new StringBuilder(); 
      while ((s = bufferedReader.readLine()) != null) { 
       builder.append(s); 
      } 

      Matcher tagmatch = htmltag.matcher(builder.toString()); 
      while (tagmatch.find()) { 
       Matcher matcher = link.matcher(tagmatch.group()); 
       matcher.find(); 
       String link = matcher.group().replaceFirst("href=\"", "") 
         .replaceFirst("\">", ""); 
       if (valid(link)) { 
        links.add(makeAbsolute(url, link)); 
       } 
      } 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return links; 
    } 

    private boolean valid(String s) { 
     if (s.matches("javascript:.*|mailto:.*")) { 
      return false; 
     } 
     return true; 
    } 

    private String makeAbsolute(String url, String link) { 
     if (link.matches("http://.*")) { 
      return link; 
     } 
     if (link.matches("/.*") && url.matches(".*$[^/]")) { 
      return url + "/" + link; 
     } 
     if (link.matches("[^/].*") && url.matches(".*[^/]")) { 
      return url + "/" + link; 
     } 
     if (link.matches("/.*") && url.matches(".*[/]")) { 
      return url + link; 
     } 
     if (link.matches("/.*") && url.matches(".*[^/]")) { 
      return url + link; 
     } 
     throw new RuntimeException("Cannot make the link absolute. Url: " + url 
       + " Link " + link); 
    } 
} 
1

Voici 2 approches utilisant LINQ to XML et regex. Bien que certaines personnes désapprouvent l'analyse HTML avec regex, ce cas particulier n'a pas d'éléments imbriqués, donc c'est une solution raisonnable. LINQ to XML ne fonctionnerait que si votre HTML est bien formé. Sinon, jetez un oeil à la HTML Agility Pack.

EDIT: pour votre exemple Elements() fonctionne avec LINQ to XML. Toutefois, si vous avez plusieurs balises HTML imbriquées, vous pouvez utiliser Descendants() pour atteindre tous les balises souhaitées.

string input = @"<p>This is some html text. my favourite website is <a href=""http://www.google.com"">google</a> and my favourite help site is <a href=""http://www.stackoverflow.com"">stackoverflow</a> and i check my email at <a href=""http://www.gmail.com"">gmail</a>. the url to my site is http://www.mysite.com. <img src=""http://www.someserver.com/someimage.jpg"" alt=""""/></p>"; 
var xml = XElement.Parse(input); 
var result = xml.Elements() 
       .Where(e => e.Name == "img" || e.Name == "a") 
       .Select(e => e.Name == "img" ? 
          e.Attribute("src").Value : e.Attribute("href").Value); 
foreach (string item in result) 
{ 
    Console.WriteLine(item); 
} 

string pattern = @"<(?:a|img).+?(?:href|src)=""(?<Url>.+?)"".*?>"; 
foreach (Match m in Regex.Matches(input, pattern)) 
{ 
    Console.WriteLine(m.Groups["Url"].Value); 
} 

EDIT # 2: en réponse à votre mise à jour au sujet RegexBuddy, je voulais souligner l'outil que je l'utilise. Expresso est un bon outil gratuit (inscription par courriel seulement, mais c'est gratuit). L'auteur a également écrit The 30 Minute Regex Tutorial que vous pouvez utiliser pour suivre et est inclus dans le fichier d'aide d'Expresso.

Questions connexes