我正在使用以下方法突出显示给定文本中的关键字。
private string HighlightSearchKeyWords(string searchKeyWord, string text)
{
Regex keywordExp = new Regex(@" ?, ?");
var pattern = @"\b(" + keywordExp.Replace(Regex.Escape(searchKeyWord), @"|") + @")\b";
Regex exp = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
return exp.Replace(text, @"<span class=""search-highlight"">$0</span>");
}
示例文本:“什么是.net编程?Pl建议几本电子书”
关键字:“。net”
当我尝试使用关键字“.net”进行搜索时,.net未在给定的示例文本中突出显示。
当我尝试使用关键词“电子书”进行搜索时,电子书会在给定的示例文本中突出显示。
会出现什么问题。任何人都可以让我知道我需要修改的地方/
答案 0 :(得分:3)
“.net”之前没有单词边界,因为\b
仅查找\w
和\W
之间的变化,.
和之间的变化(空格)属于
\W
类别,因此它们之间没有边界。
一种选择是简单地寻找“不是单词字符” - 即没有明确地检查边界,只是因为缺少单词字符,使用负面的后观:
(?<!\w)
您还可以检查任何非空白字符的内容,如下所示:
(?<!\S)
这是一个双重否定 - 在(?<=\s)
(或前一个例子中为(?<=\W)
)看起来更为明显,但这些会阻止匹配行开头的匹配。
有关这两者之间差异的示例 - 第一个与C#.NET
中的.NET匹配,而第二个则不匹配。
由于您正在使用.NET正则表达式,幸运的是您有一套相当完整的正则表达式功能 - 但值得指出的是,其他一些正则表达式实现不支持负面的后观 - 对于那些,您需要使用像这样的语法:
(?<=\W|^)
(?<=\s|^)
(在所有这些情况下,你想要另一端的等效前瞻。)
所以,以下是这四种变体在你的模式中的表现:
var pattern = @"(?<!\w)(" + keywordExp.Replace(Regex.Escape(searchKeyWord), @"|") + @")(?!\w)";
var pattern = @"(?<!\S)(" + keywordExp.Replace(Regex.Escape(searchKeyWord), @"|") + @")(?!\S)";
var pattern = @"(?<=\s|^)(" + keywordExp.Replace(Regex.Escape(searchKeyWord), @"|") + @")(?=\s|$)";
var pattern = @"(?<=\W|^)(" + keywordExp.Replace(Regex.Escape(searchKeyWord), @"|") + @")(?=\W|$)";