C# 突出显示整个单词,省略HTML

C# 突出显示整个单词,省略HTML,c#,regex,string,C#,Regex,String,我正在编写一些C#代码来解析RSS提要并突出显示内容中的特定单词,但是,我只需要突出显示HTML之外的单词。到目前为止,我已经: string contentToReplace = "This is <a href=\"test.aspx\" alt=\"This is test content\">test</a> content"; string pattern = "\b(this|the|test|content)\b"; string output = Re

我正在编写一些C#代码来解析RSS提要并突出显示内容中的特定单词,但是,我只需要突出显示HTML之外的单词。到目前为止,我已经:

string contentToReplace = "This is <a href=\"test.aspx\" alt=\"This is test content\">test</a> content";

string pattern = "\b(this|the|test|content)\b";

string output = Regex.Replace(contentToReplace, pattern, "<span style=\"background:yellow;\">$1</span>", RegexOptions.Singleline | RegexOptions.IgnoreCase);
string contentoreplace=“这是内容”;
字符串模式=“\b(此|测试|内容)\b”;
字符串输出=Regex.Replace(contentoreplace,模式,“$1”,RegexOptions.Singleline | RegexOptions.IgnoreCase);

这很好,只是它会突出显示alt标记中的单词“test”。我可以很容易地编写一个函数来剥离HTML,然后进行替换,但我需要保留HTML来显示内容。

如果输入是有效的XHTML/XML,您可以将其解析为树结构(DOM/XLinq),递归遍历树,替换文本节点中出现的所有关键字,并最终将树结构序列化回字符串

未测试的伪代码:

XNode Highlight(XElement element, List<string> keywords)
{
    var result = new XElement(element.Name);
    // copy element attributes to result

    foreach (var node in element)
    {
        if (node.Type == NodeType.Text)
        {
            var value = node.Value;
            // while value contains keyword
            // {
            //      add substring before keyword in value to result
            //      add new XElement with highlighted keyword to result
            //      remove consumed substring from value
            // }
        }
        else if (node.Type == NodeType.Element)
        {
            result.Add(Highlight((XElement)node, keywords));
        }
        else
        {
            result.Add(node);
        }
    }

    return result;
}

var output = Highlight(XElement.Parse(input), new List<string> {...}).ToString();
XNode高亮显示(XElement元素,列出关键字)
{
var result=new-XElement(element.Name);
//将元素属性复制到结果
foreach(元素中的var节点)
{
if(node.Type==NodeType.Text)
{
var值=node.value;
//而值包含关键字
// {
//在结果值中的关键字之前添加子字符串
//将带有高亮显示关键字的新元素添加到结果中
//从值中删除消耗的子字符串
// }
}
else if(node.Type==NodeType.Element)
{
添加(高亮显示((XElement)节点,关键字));
}
其他的
{
结果.添加(节点);
}
}
返回结果;
}
var output=Highlight(XElement.Parse(input),新列表{…}).ToString();

如果您有有效的XML但不想解析它,另一种解决方案是:首先将输入字符串拆分为多个部分,使每个部分只包含一个标记或文本,而不同时包含这两个部分。例如:

"This is ",
"<a href=\"test.aspx\" alt=\"This is test content\">",
"test"
"</a>"
" content"
“这是”,
""
“内容”
然后遍历各个部分,并仅将正则表达式应用于不以
开头的字符串这里是一个基本的正则表达式

private void Form1_Load(object sender, EventArgs e)
    {
        string contentToReplace = "This is <a href=\"test.aspx\" alt=\"This is test content\"> hello test world</a> content";

        string pattern = @"(>{1}.*)(test)(.*<{1})";

        string output = Regex.Replace(contentToReplace, pattern, "$1<span>$2</span>$3", RegexOptions.Singleline | RegexOptions.IgnoreCase);

        //output is :
        //This is <a href="test.aspx" alt="This is test content"> hello <span>test</span> world</a> content


        MessageBox.Show(output);
        Close();
    }
private void Form1\u加载(对象发送方,事件参数e)
{
string contentoreplace=“这是内容”;

字符串模式=@“(>{1}.*)(测试)(.*)如果输入是
”..>您好测试世界,会发生什么情况?这将匹配如下内容:
''(它不应该匹配)而无法匹配
测试“”(它应该匹配)@dtb-是的,刚刚测试了你的案子。它fails@strager-是的,你的案例也会失败。天哪,我需要一些时间来思考。我会将它标记为答案,因为它似乎获得了最多的选票。如果html文档格式不正确,这将不起作用。不要求所有标记都在html中关闭。以例如,td标记。您可以有一个未关闭的td标记,它是有效的html,但它将是无效的xml。如果文档是xhtml,这将起作用,但问题不涉及该细节。这就是为什么我的答案以“如果输入是有效的xhtml/xml”开头的原因嗯,由于内容来自随机站点,很可能不是有效的XHTML。听起来这并不容易。对shamme来说。