Trova parole chiave nel testo quando la parola chiave corrisponde a determinate condizioni – C #

Sto cercando un modo carino per fare quanto segue:

Ho un articolo che contiene tag HTML come ancore e paragrafi e così via.
Ho anche una parola chiave che ho bisogno di trovare nell’articolo e impostarla come ancora (ho qualche URL da impostare lì).
Se la parola chiave esiste nell’articolo, deve corrispondere alle seguenti condizioni DUE PRIMA di renderlo un’ancora:

  1. Non può essere all’interno di alcun tag. Ad esempio, qualcosa di simile

    keyword 

    non sarà valido / abbinato.

  2. La parola chiave non può ancora essere nell’ancora. Ad esempio, somiglia a qualcosa

     keyword 

    non sarà valido / abbinato.

    Qualsiasi aiuto sarebbe apprezzato. Grazie

Sono riuscito a farlo!

Grazie mille a questo post che mi ha aiutato molto con l’espressione xpath: http://social.msdn.microsoft.com/Forums/en-US/regexp/thread/beae72d6-844f-4a9b-ad56-82869d685037/

Il mio compito era aggiungere X parole chiave all’articolo usando la tabella di parole chiave e URL sul mio database.
Una volta trovata una corrispondenza con la parola chiave, non la cercherà di nuovo, ma cercherà di trovare la parola chiave successiva nel testo.
La “parola chiave” avrebbe potuto essere composta da più di una parola. Ecco perché ho aggiunto Replace (“”, “\ s +”).
Inoltre, ho dovuto dare la precedenza alle parole chiave più lunghe prima. Cioè se avessi:
“buona giornata” e “buona” come due parole chiave diverse: “buona giornata” vince sempre.

Questa è la mia soluzione:

 static public string AddLinksToArticle(string article, int linksToAdd) { try { //load keywords and urls var dt = new DAL().GetArticleLinks(); //sort the it IEnumerable sortedArticles = dt.OrderBy(row => row.keyword, new StringLengthComparer()); // iterate the dictionary to get keyword to replace with anchor foreach (var item in sortedArticles) { article = FindAndReplaceKeywordWithAnchor(article, item.keyword, item.url, ref linksToAdd); if (linksToAdd == 0) { break; } } return article; } catch (Exception ex) { Utils.LogErrorAdmin(ex); return null; } } private static string FindAndReplaceKeywordWithAnchor(string article, string keyword, string url, ref int linksToAdd) { //convert text to html HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(article); // \w* - means it can start with any alphanumeric charactar // \s+ - was placed to replace all white spaces (when there is more than one word). // \b - set bounderies for the keyword string pattern = @"\b" + keyword.Trim().Insert(0, "\\w*").Replace(" ", "\\s+") + @"\b"; //get all elements text propery except for anchor element var nodes = doc.DocumentNode.SelectNodes("//text()[not(ancestor::a)]") ?? new HtmlAgilityPack.HtmlNodeCollection(null); foreach (var node in nodes) { if (node.InnerHtml.Contains(keyword)) { Regex regex = new Regex(pattern); node.InnerHtml = regex.Replace(node.InnerHtml, "" + keyword + "", 1);//match only first occurrence linksToAdd--; break; } } return doc.DocumentNode.OuterHtml; } } public class StringLengthComparer : IComparer { public int Compare(string x, string y) { return y.Length.CompareTo(x.Length); } } 

Spero che possa aiutare qualcuno in futuro.