2009-06-11 4 views
2

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

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

Некоторые пояснения:

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

/images/header.jpg 

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

www.stackoverflow/images/header.jpg 

ответ

12

Вы не хотите, регулярное выражение, вы хотите синтаксический анализатор. From this question:

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. –

+8

Ничего себе, это битва за «Па [ou] lo's :-) – paxdiablo

0

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

  • подстанции;
  • regexes; и
  • парсеры.

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

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

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

2

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

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

Это будет соответствовать в исходных текстах атрибутов с разделителями одинарными или двойными кавычками.

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

0

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

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

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'] } 

И вы сделали!

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; 
} 
Смежные вопросы