Регулярное выражение для поиска src из тега IMG

2

У меня есть веб-страница. Из этого я хочу найти все теги IMG и получить SRC этих тегов IMG.

Каким будет регулярное выражение для этого.

Некоторое объяснение:

Я очищаю веб-страницу. Все данные отображаются корректно, кроме изображений. Чтобы решить эту проблему, у меня есть идея, найти SRC и заменить ее: например,

/images/header.jpg

и замените это на

www.stackoverflow/images/header.jpg
Теги:

5 ответов

12
Лучший ответ

Вы не хотите регулярного выражения, вам нужен синтаксический анализатор. Из этого вопроса:

class Program
{
    static void Main(string[] args)
    {
        var web = new HtmlWeb();
        var doc = web.Load("http://www.stackoverflow.com");

        var nodes = doc.DocumentNode.SelectNodes("//img[@src]");

        foreach (var node in nodes)
        {
                Console.WriteLine(node.src);
        }
    }
}
  • 0
    Это зависит от требований человека. Что если он захочет извлечь это из пользовательского ввода?
  • 2
    Он все еще может загрузить его в анализатор, и даже более того, если это от пользователя. Обсуждается ad-nauseam, почему регулярные выражения - плохая идея для разбора HTML.
Показать ещё 1 комментарий
2

Как уже отмечалось, регулярное выражение не является идеальным решением, но вы обычно можете создать тот, который достаточно хорош для работы. Это то, что я бы использовал:

string newHtml = Regex.Replace(html,
      @"(?<=<img\s+[^>]*?src=(?<q>['""]))(?<url>.+?)(?=\k<q>)",
      m => "http://www.stackoverflow.com" + m.Value);

Он будет соответствовать атрибутам src, ограниченным одинарными или двойными кавычками.

Конечно, вам нужно будет изменить лямбда/делегат, чтобы выполнить свою собственную логику замены, но вы получаете идею:)

0
/// <summary>
/// Gets the src from an IMG tag
/// Assigns proper values to link and name, if the htmlId matches the pattern
/// </summary>
/// <param name="htmlTd">Html containing IMG tag</param>
/// <param name="link">Contains the src contents</param>
/// <param name="name">Contains img element content</param>
/// <returns>true if success, false otherwise</returns>
public static bool TryGetImgDetails(string htmlTd, out string link, out string name)
{
    link = null;
    name = null;

    string pattern = "<img\\s*src\\s*=\\s*(?:\"(?<link>[^\"]*)\"|(?<link>\\S+))\\s*>(?<name>.*)\\s*</img>";

    if (Regex.IsMatch(htmlTd, pattern))
    {
        Regex r = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
        link = r.Match(htmlTd).Result("${link}");
        name = r.Match(htmlTd).Result("${name}");
        return true;
    }
    else
        return false;
}
0

Я должен согласиться с толпой парсера на этом. В порядке возрастания сложности ввода иерархия, которую я выбираю,:

  • подстроки;
  • ; регулярные выражения и
  • парсеры.

В то время как регулярные выражения могут обрабатывать гораздо более сложные входы, чем простые операции подстроки, они, как правило, довольно легко удаляются, когда сталкиваются с действительно волосатыми возможностями ввода языков разметки свободной формы.

XML DOM-парсеры будут самым простым решением для этой проблемы.

Вы можете использовать регулярные выражения (и они будут работать достаточно хорошо, если вы ограничите входной формат, например, чтобы гарантировать, что теги img не пересекают границы строк и т.д.), но простота решения на основе парсера будет вызывать регулярные выражения из воды для многострочных тегов DOM атрибутов в любом порядке.

0

Помните, что источник может быть сгенерирован с помощью javascript, поэтому вы не сможете "просто" выполнить замену регулярных выражений для img src.

Использование Mechanize/Hpricot/Nokogiri в ruby:

require 'mechanize'
agent = WWW::Mechanize.new
page  = agent.get('http://www.google.com')
(page/"img").each { |img| puts img['src'] = "http://www.yahoo.com" + img['src'] }

И все готово!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню