什么正则表达式将匹配文本,不包括 HTML 标记中的内容?

Posted

技术标签:

【中文标题】什么正则表达式将匹配文本,不包括 HTML 标记中的内容?【英文标题】:What regex will match text excluding what lies within HTML tags? 【发布时间】:2010-09-15 20:08:01 【问题描述】:

我正在为需要突出显示搜索词的搜索结果页面编写代码。这些术语恰好出现在表格单元格中(应用程序正在遍历 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 标签之外?它不必是超级硬核。我认为只要确保匹配不在 之间就可以了。

【问题讨论】:

如果有人在您的示例中搜索 Fred,是否应该突出显示? 是的。谢谢你的慰问。好问题。我将编辑问题。 【参考方案1】:

这个正则表达式应该可以完成这项工作:(?&lt;!&lt;[^&gt;]*)(regex you want to check: Fred|span) 它检查从匹配字符串开始向后退的正则表达式 &lt;[^&gt;]* 是不可能匹配的。

修改后的代码如下:

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);

【讨论】:

非常感谢!你救了我的一天! :) 这是一段很棒的代码。你应该得到比你得到的更多的选票。非常感谢。 4 年后,您的回答又帮助了另一个人。谢谢!【参考方案2】:

您可以将正则表达式用于平衡组和反向引用,但我强烈建议您在此处使用parser。

【讨论】:

【参考方案3】:

嗯,我不是 C# 程序员,所以我不知道它使用的正则表达式的味道,但 (?!<.>) 应该忽略标签内的任何内容。它会强制你在 HTML 代码中使用 < >,但无论如何你都应该这样做。

【讨论】:

为了匹配我在示例中描述的“类”,“类”这个词在你的正则表达式中应该放在哪里?我不明白如何使用你的正则表达式。就其本身而言,它似乎匹配整个短语中的每个字符位置。 正则表达式 "(?!<.>)" 只是一个否定的前瞻;它说,“从这个位置来看,我们不会看到看起来像标签的东西。”它不会匹配任何东西,也不会阻止匹配标签内部或外部的任何东西。【参考方案4】:

编写一个可以处理 CDATA 部分的正则表达式会很困难。您可能不再假设 > 关闭标签。

例如,"&lt;span class="CustomerName&gt;Fred.&lt;/span&gt; is a good customer (&lt;![CDATA[ &gt;10000$ ]]&gt; )"

解决方案是(如前所述)解析器。他们在处理您在CDATA 中发现的那种混乱方面要好得多。 madgnome 的向后检查不能用于从]]&gt; 中查找起始&lt;![CDATA,因为CDATA 部分可能包含文字&lt;![CDATA

【讨论】:

我知道解决方案并不完美,但权衡了所有的起起落落,这是我迄今为止找到的最好的解决方案。

以上是关于什么正则表达式将匹配文本,不包括 HTML 标记中的内容?的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式匹配关闭的 HTML 标记

python中的正则表达式

正则表达式提取特定 HTML 标记中的纯文本 [重复]

如何使用正则表达式匹配从 xml 文件中搜索和替换包含占位符标记的文本。 VB.net 或 C#

正则表达式在 html 锚标记内不匹配 [重复]

用于在 HTML 标记中提取特定文本内容的正则表达式