我有一个名为HighlightKeywords的辅助方法,我在查看搜索结果时在论坛上使用,以突出显示用户搜索过的帖子中的关键字。
我遇到的问题是,例如用户搜索关键字“hotmail”,然后HighlightKeywords方法找到该关键字的匹配项,并用指定要应用的样式的span标记包装它,它在内部查找匹配项html锚标签,在某些情况下还有图像标签。因此,当我将突出显示的帖子渲染到屏幕时,html标签会被破坏(由于跨度插入其中)。
这是我的功能:
public static string HighlightKeywords(this string s, string keywords, string cssClassName)
{
if (s == string.Empty || keywords == string.Empty)
{
return s;
}
string[] sKeywords = keywords.Split(' ');
foreach (string sKeyword in sKeywords)
{
try
{
s = Regex.Replace(s, @"\b" + sKeyword + @"\b", string.Format("<span class=\"" + cssClassName + "\">{0}</span>", "$0"), RegexOptions.IgnoreCase);
}
catch {}
}
return s;
}
防止这种情况破坏的最佳方法是什么?即使我只是简单地排除锚标记内发生的任何匹配(无论是网络地址还是电子邮件地址)还是图像标记?
答案 0 :(得分:4)
没有。你不能这样做。至少,不是不会破坏的方式。正则表达式不能解析HTML的任务。真的对不起。你也想读这个咆哮:RegEx match open tags except XHTML self-contained tags
所以,您可能需要解析HTML(我听说HtmlAgilityPack很好),然后只匹配文档的某些部分 - 不包括锚标记等。
答案 1 :(得分:1)
我遇到了同样的问题,想出了这项工作
public static string HighlightKeyWords(string s, string[] KeyWords)
{
if (KeyWords != null && KeyWords.Count() > 0 && !string.IsNullOrEmpty(s))
{
foreach (string word in KeyWords)
{
s = System.Text.RegularExpressions.Regex.Replace(s, word, string.Format("{0}", "{0}$0{1}"), System.Text.RegularExpressions.RegexOptions.IgnoreCase);
}
}
s = string.Format(s, "<mark class='hightlight_text_colour'>", "</mark>");
return s;
}
看起来有些可怕,但我推迟添加html标签,直到正则表达式匹配所有关键字,在{0}和{1}位置添加了乞讨和结束html标记,而不是标签。然后我在最后添加html标签, 使用圈内的占位符。
如果关键字{0}或{1}作为关键字传入,则仍会中断。
答案 2 :(得分:0)
关于使用正则表达式解析html的所有免责声明,这是一种简单的方法。
以hotmail
为例,以最简单的形式展示技术,这里是我们简单的正则表达式:
<a.*?</a>|(hotmail)
交替的左侧匹配完整的<a ... </a>
标签。我们将忽略这些匹配。右侧匹配并捕获hotmail
到组1,我们知道它们是正确的hotmail
,因为它们与左侧的表达式不匹配。
此程序显示了如何使用正则表达式(请参阅online demo底部的结果):
using System;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
class Program
{
static void Main() {
var myRegex = new Regex(@"<a.*?</a>|(hotmail)");
string s1 = @"replace this=> hotmail not that => <a href=""http://hotmail.com"">hotmail</a>";
string replaced = myRegex.Replace(s1, delegate(Match m) {
if (m.Groups[1].Value != "") return "<span something>hotmail</span>";
else return m.Value;
});
Console.WriteLine("\n" + "*** Replacements ***");
Console.WriteLine(replaced);
Console.WriteLine("\nPress Any Key to Exit.");
Console.ReadKey();
} // END Main
} // END Program
参考
How to match (or replace) a pattern except in situations s1, s2, s3...