2009-05-12 3 views
0

Ich habe die folgende Regex alle Link-Tags erzeugt auf einer Seite passen in unserem speziell cmsGet Attribut „Titel“ von HTML-Link mit Regex

<a\s+((?:(?:\w+\s*=\s*)(?:\w+|"[^"]*"|'[^']*'))*?\s*href\s*=\s*(?<url>\w+|"[^"]*"|'[^']*')(?:(?:\s+\w+\s*=\s*)(?:\w+|"[^"]*"|'[^']*'))*?)>.+?</a> 

Wir verwenden C# durch alle Spiele dieser Schleife und Fügen Sie vor dem Rendern des Seiteninhalts zu jedem Link ein Onclick-Ereignis hinzu (zum Verfolgen von Software). Ich muss die Verbindung analysieren und einen Parameter zur onclick Funktion hinzufügen, die der "Verbindungsname" ist.

ich die Regex ändern würde die folgenden Untergruppen

  • Der Titel-Attribut des Link
  • Wenn der Link enthält ein Image-Tag erhalten der Alt-Text des Bildes
  • Die bekommen Text des Links

Ich kann dann die Übereinstimmung jeder Untergruppe überprüfen, um den relevanten Namen des Links zu erhalten.

Wie würde ich die obige Regex ändern, um dies zu tun, oder könnte ich das gleiche denken mit C# -Code?

+0

Sie verwenden ASP.NET, um diese Seite zu generieren? –

+0

Würdest du bitte einen Freund hinzufügen, füge das bitte zu den FAQ hinzu? – annakata

+0

Ja Ich benutze ASP.NET, um die Seite zu generieren – Sheff

Antwort

6

Regexes sind grundsätzlich schlecht beim Parsen von HTML (siehe Can you provide some examples of why it is hard to parse XML and HTML with a regex? für warum). Was Sie brauchen, ist ein HTML-Parser. Beispiele finden Sie unter Can you provide an example of parsing HTML with your favorite parser? mit einer Vielzahl von Parsern.

Insbesondere könnten Sie interessiert sein an der HTMLAgilityPack answer.

+0

Ja, ich kann sehen, dass Regex ist nicht besonders gut bei der Analyse von HTML, was ich (und mein Mangel an Regex-Wissen) Ich habe damit zu kämpfen. Bedenkt im Verstand, kann ich nicht garantieren, dass diese App xhtml hat, können Sie einen guten C# Parser empfehlen, der das oben genannte erreichen würde? – Sheff

+0

Sorry verpasste Ihren Anker zum HTMLAgilityPack, krank zu sehen, danke – Sheff

2

Versuchen Sie folgendes:

Regex reg = new Regex("<a[^>]*?title=\"([^\"]*?\"[^>]*?>"); 

Ein paar gotchas:

  • Dies wird übereinstimmen ist case-sensitive, Sie können einstellen, dass
  • Dies erwartet der Titel-Attribut sowohl existiert und wird zitiert
    • Natürlich, wenn das Titelattribut nicht existiert, wollen Sie wahrscheinlich nicht die Übereinstimmung irgendwelcher Weg?

Um die Gruppen Sammlung zu extrahieren, verwenden:

reg.Match("<a href=\"#\" title=\"Hello\">Howdy</a>").Groups[1].Value 
+0

Leider möchte ich übereinstimmen, wenn kein title-Tag vorhanden ist der Inhalt in diesem bestimmten cms ist sehr schlechte Qualität html also Wenn der Titel nicht vorhanden ist, muss ich überprüfen Bild alt dann Link Text. – Sheff

0

Dank Chaos. Owens, der mich auf die HtmlAgilityPack-Bibliothek hinweist, ist großartig. Am Ende habe ich es benutzt, um mein Problem zu lösen. Ich würde diese Bibliothek trotzig anderen empfehlen.

HtmlDocument htmldoc = new HtmlDocument(); 
    htmldoc.LoadHtml(content); 
    HtmlNodeCollection linkNodes = htmldoc.DocumentNode.SelectNodes("//a[@href]"); 
    if (linkNodes != null) 
    { 
     foreach (HtmlNode linkNode in linkNodes) 
     { 
      string linkTitle = linkNode.GetAttributeValue("title", string.Empty); 
      //If no title attribute exists check for an image alt tag 
      if (linkTitle == string.Empty) 
      { 
       HtmlNode imageNode = linkNode.SelectSingleNode("img[@alt]"); 
       if (imageNode != null) 
       { 
        linkTitle = imageNode.GetAttributeValue("alt", string.Empty); 
       } 
      } 
      //If no image alt tag check for span with text 
      if (linkTitle == string.Empty) 
      { 
       HtmlNode spanNode = linkNode.SelectSingleNode("span"); 
       if (spanNode != null) 
       { 
        linkTitle = spanNode.InnerText; 
       } 
      } 

      if (linkTitle == string.Empty) 
      { 
       if (!linkNode.HasChildNodes) 
       { 
        linkTitle = linkNode.InnerText; 
       } 
      } 

     } 
    } 
+0

Ich mag das, obwohl ich nicht glaube, dass es beabsichtigt war: * "Ich würde ** diese Bibliothek allen anderen empfehlen." * – JDB