我正在为需要突出显示搜索字词的搜索结果页面编写代码。这些术语碰巧发生在表格单元格中(应用程序正在迭代GridView行单元格),这些表格单元格可能包含HTML。
目前,我的代码看起来像这样(相关的帅哥如下所示):
const string highlightPattern = @"<span class=""Highlight"">$0</span>";
DataBoundLiteralControl litCustomerComments = (DataBoundLiteralControl)e.Row.Cells[CUSTOMERCOMMENTS_COLUMN].Controls[0];
// Turn "term1 term2" into "(term1|term2)"
string spaceDelimited = txtTextFilter.Text.Trim();
string pipeDelimited = string.Join("|", spaceDelimited.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries));
string searchPattern = "(" + pipeDelimited + ")";
// Highlight search terms in Customer - Comments column
e.Row.Cells[CUSTOMERCOMMENTS_COLUMN].Text = Regex.Replace(litCustomerComments.Text, searchPattern, highlightPattern, RegexOptions.IgnoreCase);
令人惊讶的是它有效。但是,有时我匹配的文本是HTML,如下所示:
<span class="CustomerName">Fred</span> was a classy individual.
如果你搜索“class”我希望突出显示代码将“class”包装在“classy”中,但当然不是那里恰好存在的HTML属性“class”!如果您搜索“Fred”,则应突出显示。
那么什么是一个好的正则表达式,以确保匹配只发生在html标签之外?它不一定是超级铁杆。只需确保匹配不在&lt;和&gt;我认为会很好。
答案 0 :(得分:11)
这个正则表达式应该可以完成这项任务:(?<!<[^>]*)(regex you want to check: Fred|span)
它检查从匹配的字符串开始向后退的正则表达式<[^>]*
是否无法匹配。
以下修改后的代码:
const string notInsideBracketsRegex = @"(?<!<[^>]*)";
const string highlightPattern = @"<span class=""Highlight"">$0</span>";
DataBoundLiteralControl litCustomerComments = (DataBoundLiteralControl)e.Row.Cells[CUSTOMERCOMMENTS_COLUMN].Controls[0];
// Turn "term1 term2" into "(term1|term2)"
string spaceDelimited = txtTextFilter.Text.Trim();
string pipeDelimited = string.Join("|", spaceDelimited.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries));
string searchPattern = "(" + pipeDelimited + ")";
searchPattern = notInsideBracketsRegex + searchPattern;
// Highlight search terms in Customer - Comments column
e.Row.Cells[CUSTOMERCOMMENTS_COLUMN].Text = Regex.Replace(litCustomerComments.Text, searchPattern, highlightPattern, RegexOptions.IgnoreCase);
答案 1 :(得分:2)
您可以使用正则表达式来平衡组和反向引用,但我强烈建议您在此处使用parser。
答案 2 :(得分:0)
嗯,我不是C#程序员,所以我不知道它使用的正则表达式的味道,但是(?!&lt;。+?&gt;)应该忽略标签内的任何内容。它会强制您在HTML代码中使用&amp;#60&amp;#62,但无论如何你应该这样做。
答案 3 :(得分:0)
编写一个可以处理CDATA部分的正则表达式会很困难。您可能不再认为&gt;关闭标签。
例如,"<span class="CustomerName>Fred.</span> is a good customer (<![CDATA[ >10000$ ]]> )"
解决方案是(如前所述)解析器。他们在处理CDATA
中发现的混乱方面要好得多。 madgnome的向后检查不能用于从<![CDATA
查找起始]]>
,因为CDATA
部分可能包含文字<![CDATA
。