2011-09-25 7 views
2

J'ai un flux de source de site Web que j'essaye d'analyser. Mon Regex actuel est le suivant:Aide simple regex en utilisant C# (motif Regex inclus)

Regex pattern = new Regex (
@"<a\b    # Begin start tag 
    [^>]+?    # Lazily consume up to id attribute 
    id\s*=\s*['""]?thread_title_([^>\s'""]+)['""]? # $1: id 
    [^>]+?    # Lazily consume up to href attribute 
    href\s*=\s*['""]?([^>\s'""]+)['""]?    # $2: href 
    [^>]*    # Consume up to end of open tag 
    >     # End start tag 
    (.*?)           # $3: name 
    </a\s*>   # Closing tag", 
RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); 

Mais cela ne correspond plus aux liens. J'ai inclus un exemple de chaîne here.

Fondamentalement, je suis en train de les faire correspondre:

<a href="http://visitingspain.com/forum/f89/how-to-get-a-travel-visa-3046631/" id="thread_title_3046631">How to Get a Travel Visa</a> 

"http://visitingspain.com/forum/f89/how-to-get-a-travel-visa-3046631/" is the **Link** 
304663` is the **TopicId** 
"How to Get a Travel Visa" is the **Title** 

Dans l'exemple que j'ai posté, il y a au moins 3, je ne comptais pas les autres.

Aussi j'utilise RegexHero (en ligne et gratuit) pour voir mon correspondant interactivement avant de l'ajouter au code.

+1

Utilisez HtmlAgilityPack. – SLaks

+0

@Joan Venge Pour la référence: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags –

+0

Merci pst, je n'en ai pas vu un. –

Répondre

4

Pour être complet, voici comment cela se fait avec le Html Agility Pack, qui est un analyseur HTML robuste pour .Net (également disponible via NuGet, l'installation prend donc environ 20 secondes).

Chargement du document, l'analyse, et de trouver les 3 liens est aussi simple que:

string linkIdPrefix = "thread_title_"; 
HtmlWeb web = new HtmlWeb(); 
HtmlDocument doc = web.Load("http://jsbin.com/upixof"); 
IEnumerable<HtmlNode> threadLinks = doc.DocumentNode.Descendants("a") 
           .Where(link => link.Id.StartsWith(linkIdPrefix)); 

C'est, vraiment. Maintenant, vous pouvez facilement obtenir les données:

foreach (var link in threadLinks) 
{ 
    string href = link.GetAttributeValue("href", null); 
    string id = link.Id.Substring(linkIdPrefix.Length); // remove "thread_title_" 
    string text = link.InnerHtml; // or link.InnerText 
    Console.WriteLine("{0} - {1}", id, href); 
} 
+0

Merci Kobi, je vais essayer ça maintenant. –

1

Don't do that (bien, almost, mais ce n'est pas pour tout le monde). Parsers sont destinés à ce type de chose.

+2

Merci, mais j'ai besoin d'un quickfix, pas un changement majeur. De plus, c'est un outil personnel que personne n'utilise de toute façon. De plus, je vois beaucoup d'exemples de pratiques similaires dans le code de production, donc je pense que même la plupart des programmeurs ne suivent pas ces bonnes pratiques. –

3

Ceci est assez simple, le balisage a changé, et maintenant l'attribut href apparaît avant la id:

<a\b    # Begin start tag 
    [^>]+?    # Lazily consume up to href attribute 
    href\s*=\s*['""]?([^>\s'""]+)['""]?    # $1: href 
    [^>]+?    # Lazily consume up to id attribute 
    id\s*=\s*['""]?thread_title_([^>\s'""]+)['""]? # $2: id 
    [^>]*    # Consume up to end of open tag 
    >     # End start tag 
    (.*?)           # $3: name 
    </a\s*>   # Closing tag 

Notez que:

  • Ceci est principalement la raison pour laquelle cela est une mauvaise idée.
  • Les numéros de groupe ont changé. Vous pouvez utiliser des groupes nommés à la place, pendant que vous y êtes: (?<ID>[^>\s'""]+) au lieu de ([^>\s'""]+).
  • Les citations sont encore échappés (cela devrait être OK dans les jeux de caractères)

Exemple sur regex hero.

+0

Merci, dans votre exemple de lien, est-il modifié? Quand je l'ouvre, il dit 0 matchs. –

+0

@Joan - Essayez à nouveau, cela n'a pas fonctionné sur le lien. – Kobi

+0

Merci, je viens de l'essayer, mais toujours 0 matchs. –