我正在寻找一种很好的方法来执行以下操作:
我有一篇文章,其中包含 HTML 标记,例如锚点和段落等。
我也有我需要在文章中找到的关键字并将其设置为锚点(我有一些网址要设置在那里)。
如果文章中确实存在关键字,则在使其成为锚点之前,它应该匹配以下两个条件:
它不能在任何标签内。例如,像
<img alt="keyword">
将无效/不匹配。
关键字不能已经在锚点内。例如,类似的东西
<a>keyword</a>
将无效/不匹配。
任何帮助,将不胜感激。谢谢
我正在寻找一种很好的方法来执行以下操作:
我有一篇文章,其中包含 HTML 标记,例如锚点和段落等。
我也有我需要在文章中找到的关键字并将其设置为锚点(我有一些网址要设置在那里)。
如果文章中确实存在关键字,则在使其成为锚点之前,它应该匹配以下两个条件:
它不能在任何标签内。例如,像
<img alt="keyword">
将无效/不匹配。
关键字不能已经在锚点内。例如,类似的东西
<a>keyword</a>
将无效/不匹配。
任何帮助,将不胜感激。谢谢
我已经成功完成了!
非常感谢这篇文章,它对 xpath 表达式有很大帮助:http:
//social.msdn.microsoft.com/Forums/en-US/regexp/thread/beae72d6-844f-4a9b-ad56-82869d685037/
我的任务是使用我数据库中的关键字和 url 表将 X 个关键字添加到文章中。
一旦关键字匹配 - 它不会再次搜索它,但会尝试在文本中找到下一个关键字。
“关键字”可能由多个单词组成。这就是我添加替换(“”,“\s+”)的原因。
另外,我必须首先优先考虑最长的关键字。也就是说,如果我有:
“美好的一天”和“美好的”作为两个不同的关键字——“美好的一天”总是获胜。
这是我的解决方案:
static public string AddLinksToArticle(string article, int linksToAdd)
{
try
{
//load keywords and urls
var dt = new DAL().GetArticleLinks();
//sort the it
IEnumerable<ArticlesRow> 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, "<a href=\"" + url + "\">" + keyword + "</a>", 1);//match only first occurrence
linksToAdd--;
break;
}
}
return doc.DocumentNode.OuterHtml;
}
}
public class StringLengthComparer : IComparer<string>
{
public int Compare(string x, string y)
{
return y.Length.CompareTo(x.Length);
}
}
希望它会在未来对某人有所帮助。