RegEx.替换但排除html标记中的匹配项

本文关键字:替换 排除 html RegEx | 更新日期: 2023-09-27 17:57:27

我有一个名为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;
    }

防止这种情况发生的最佳方法是什么?即使我可以简单地排除锚标签(无论是网络地址还是电子邮件地址)或图像标签中发生的任何匹配?

RegEx.替换但排除html标记中的匹配项

否。你不能那样做。至少,不会以一种不会破裂的方式。正则表达式无法完成解析HTML的任务。我真的很抱歉。你也会想读这篇咆哮:RegEx匹配除了XHTML自包含标签之外的开放标签

因此,您可能需要解析HTML(我听说HtmlAgilityPack很好),然后只在文档的某些部分内匹配-不包括锚标记等。

我遇到了同样的问题,围绕提出了这项工作

    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标记的添加,直到regex表达式匹配了所有关键字,添加了乞求和结束html标记的{0}和{1}占位符,而不是标记。然后我在末尾添加html标签,使用循环内部的占位符。

如果将关键字{0}或{1}作为关键字传入,则仍将中断。

Marcus,重新提出这个问题,因为它有一个没有提到的简单解决方案。这种情况听起来非常类似于匹配(或替换)模式,除了在s1、s2、s3等情况下。

关于使用regex解析html的所有免责声明,这里有一个简单的方法

hotmail为例,以最简单的形式展示该技术,下面是我们的简单正则表达式:

<a.*?</a>|(hotmail)

交替的左侧与完整的<a ... </a>标签匹配。我们将忽略这些匹配。右侧将hotmail匹配并捕获到组1,我们知道它们是右侧hotmail,因为它们与左侧的表达式不匹配。

这个程序展示了如何使用正则表达式(见在线演示底部的结果):

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

参考

如何匹配(或替换)除s1、s2、s3情况外的模式…