извлечь все URL из строки - PullRequest
2 голосов
/ 20 марта 2010

У меня есть строка текста, содержащая html, и мне нужно извлечь каждый URL (скорее всего, в img или тегах), чтобы создать общий список строковых объектов. Я хочу только URL-адреса из тегов HTML, а не в тексте. Есть ли простой способ сделать это или мне придется прибегать к регулярным выражениям?

Если бы мне пришлось прибегнуть к регулярным выражениям, не могли бы вы мне помочь с этим? :)

UPDATE: Чтобы ответить Seph, ввод будет стандартный 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>

а я хочу

конечный результат должен быть Все URL в любом HTML-теге, игнорируя те, которые являются "простым текстом"

UPPERDATE Хотя он удалил свой ответ, я хочу поблагодарить Джерри Булларда за то, что он привлек мое внимание Regex Buddy (http://www.regexbuddy). Я хотел бы подтвердить ваш ответ, но он пропал. Верните его, и вы получите голос!

Ответы [ 3 ]

1 голос
/ 20 марта 2010

Как-то так должно помочь:

    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 голос
/ 20 марта 2010

Вот 2 подхода с использованием LINQ to XML и regex. Хотя некоторые люди недовольны анализом HTML с помощью регулярных выражений, в этом конкретном случае нет вложенных элементов, поэтому это разумное решение. LINQ to XML будет работать, только если ваш HTML правильно сформирован. В противном случае взгляните на HTML Agility Pack .

РЕДАКТИРОВАТЬ: для вашего образца Elements() работает с LINQ to XML. Однако, если у вас много вложенных тегов HTML, вы можете использовать Descendants(), чтобы достичь всех желаемых тегов.

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);
}

РЕДАКТИРОВАТЬ # 2: в ответ на ваше обновление о RegexBuddy, я хотел бы указать на инструмент, который я использую. Expresso - хороший бесплатный инструмент (только регистрация по электронной почте, но она бесплатная). Автор также написал 30-минутное руководство по регулярным выражениям , которое вы можете использовать, чтобы следовать ему, и включено в файл справки Expresso.

0 голосов
/ 20 марта 2010

Этот код может быть полезен :) Взято из 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...