2009-05-27 8 views
0

Je ne peux vraiment pas m'expliquer comment faire mieux, je peux faire des expressions regex assez simples, mais les plus complexes me bousculent vraiment.Quel est le REGEX pour faire correspondre ce modèle dans un document html en C#?

Le message suivant apparaît dans les documents HTML spécifiques:

<span id="label"> 
<span> 
<a href="http://variableLink">Joe Bloggs</a> 
now using 
</span> 
<span> 
' 
<a href="/variableLink/">Important Data</a> 
' 
</span> 
<span> 
on 
<a href="/variableLink">Important data 2</a> 
</span> 
</span> 

je dois extraire les points les deux « données importantes » et pourrait passer des heures à travailler le regex pour le faire (j'utilise le .net. Bibliothèque Regex en C# 3.5)

+0

Je ne peux pas vous aider, j'ai peur, mais si vous avez besoin d'aide sur .NET RegEx, essayez Expresso http://www.ultrapico.com/Expresso.htm Il est gratuit et vraiment très bon pour les tests RegEx . –

+1

Doit-on utiliser regexp, ou pouvez-vous utiliser une bibliothèque d'analyse HTML comme HTML Agility Pack (http://www.codeplex.com/htmlagilitypack)? –

+0

Je pourrais utiliser n'importe quoi, ne pas avoir besoin d'être regex. –

Répondre

4

Comme souvent dit avant, les expressions régulières ne sont généralement pas le bon outil pour analyser HTML, XML et amis - pensez à utiliser des bibliothèques d'analyse HTML ou XML. Si vous voulez ou devez vraiment utiliser des expressions régulières, les éléments suivants correspondent souvent au contenu des balises, mais peuvent dans certains cas échouer.

<a href="[^"]*">(?<data>[^<]*)</a> 

Cette expression correspond à tous les liens ne commençant pas par http:// - c'est la seule différence obviouse je peux voir entre les liens.

<a href="(?!http://)[^"]*">(?<data>[^<]*)</a> 
+1

Cela ne correspondra-t-il pas également à "Joe Bloggs" et à tout autre lien dans le document html? –

+0

Ça ramasse Joe Bloggs aussi. Il a dit qu'il veut seulement les 2 points "importants". –

+0

Oui, j'ai remarqué cela.Je ne sais pas comment il veut différencier entre ces liens. Matthew devra élaborer la différence. –

0

Cherchez-derrière et regarder look-ahead syntaxe pour .NET et l'utiliser pour rechercher les balises d'ancrage dans le code HTML. This site peut vous aider. Comme alternative aux expressions régulières, vous pouvez envisager d'utiliser un System.Xml.XPath.XPathNavigator pour adresser ces nœuds directement.

0

Mon Regex est un peu rouillé, mais quelque chose le long des lignes de ce qui suit peut aider (même si elle aura probablement besoin d'un certain réglage fin):

(?<=\<a href="/variableLink[/]?"\>)(.*)+(?=</a>) 
0
<a\shref.*?"/variableLink/?">(.*)</a> 

Le premier groupe contient le nom des ancres . Testé avec Expresso. Fonctionne sur le texte d'exemple que vous avez fourni.
Mise à jour: fonctionne également avec Snippy.

Regex regex = new Regex(@"<a\shref.*?""/variableLink/?"">(.*)</a>", RegexOptions.Multiline); 
foreach (Match everyMatch in regex.Matches(sText)) 
{ 
    Console.WriteLine("{0}", everyMatch.Groups[1]); 
} 

Sorties:

Important Data 
Important data 2 
4

Le ci-dessous utilise HtmlAgilityPack. Il imprime n'importe quel texte dans un deuxième ou plus tard dans l'identifiant "label". Bien sûr, il est relativement simple de modifier le XPath pour faire quelque chose d'un peu différent.

HtmlDocument doc = new HtmlDocument(); 
    doc.Load(new StringReader(@"<span id=""label""> 
<span> 
<a href=""http://variableLink"">Joe Bloggs</a> 
now using 
</span> 
<span> 
' 
<a href=""/variableLink/"">Important Data</a> 
' 
</span> 
<span> 
on 
<a href=""/variableLink"">Important data 2</a> 
</span> 
</span> 
")); 
    HtmlNode root = doc.DocumentNode; 

    HtmlNodeCollection anchors; 
    anchors = root.SelectNodes("//span[@id='label']/span[position()>=2]/a/text()"); 
    IList<string> importantStrings; 
    if(anchors != null) 
    { 
     importantStrings = new List<string>(anchors.Count); 
     foreach(HtmlNode anchor in anchors) 
     importantStrings.Add(((HtmlTextNode)anchor).Text); 
    } 
    else 
     importantStrings = new List<string>(0); 

    foreach(string s in importantStrings) 
     Console.WriteLine(s); 
+1

Je sais qu'il a demandé regex, mais je suis entièrement d'accord regex serait nul pour ce genre de chose. Pas impossible de vous déranger, mais sacrément presque impossible à maintenir parce que les expressions régulières pour html et similaires se retrouvent généralement avec des craploads d'évasions. Surtout si vous cherchez à aller au-delà d'une seule étiquette. – Kris

Questions connexes