2009-08-23 56 views
2

我正在编写一些C#代码来解析RSS提要并突出显示内容中的特定整个单词,但是,我只需要突出显示HTML之外的单词。到目前为止,我有:突出显示整个单词,省略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); 

这工作正常,除了它会突出显示单词“测试”在alt标记。我可以轻松地编写一个剥离HTML的函数,然后执行替换,但我需要保留HTML以显示内容。

回答

2

如果输入是有效的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(); 
+0

圣snikey,那将需要一些时间来绕到我的头。我将它标记为答案,因为它似乎获得了最多的选票。 – 2009-08-24 02:59:10

+0

如果html文档格式不正确,这将不起作用。并不要求所有标签都在html中关闭。以td标签为例。你可以有一个未封闭的TD标签,它是有效的HTML,但它将是一个无效的XML。如果文档是xhtml,这将起作用,但问题没有提到细节。 – Steve 2009-08-24 14:25:57

+0

这就是为什么我的答案以“** If **输入有效的XHTML/XML”开头的原因 – dtb 2009-08-24 14:32:20

1

另一种解决方案,如果您有有效的XML,但不想对它进行解析:首先拆分输入字符串转换部分,使得每一部分仅包含一个标签或文本,但不是都。例如:

"This is ", 
"<a href=\"test.aspx\" alt=\"This is test content\">", 
"test" 
"</a>" 
" content" 

通过零件然后遍历和您的正则表达式仅适用于不'<'开头的字符串。最后,将所有部分连接回单个字符串。

-2

这是一个基本的。

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(); 
    } 
+0

如果输入是“... ...> hello test test world <...”'会发生什么?这个正则表达式是否替换了“test”或者只是第一个? – dtb 2009-08-23 20:02:38

+0

这会匹配类似:''> test <“src =”...“/>''(它不应该匹配),并且不匹配”test“(它应该匹配) –
                        <span class= strager 2009-08-23 23:33:43

+0

@ dtb - 是的,只是测试你的情况。它失败 – Steve 2009-08-24 02:45:39