如果文本不在某些指定的HTML标记内,请替换它

时间:2009-06-06 22:34:35

标签: c# regex

我有一个应该替换的单词列表 HTML页面,但仅当单词不在标签列表中时(如A B I)

所以如果有文字:

<p> some text and XXX term <a href="http://some-XXX-bla.com">good morning XXX world</a> other text and XXX term <b>another XXX inside other sentance</b> </p>

和XXX应替换为YYY,而最终文本应为:

<p> some text and YYY term <a href="http://some-XXX-bla.com">good morning XXX world</a> other text and YYY term <b>another XXX inside other sentance</b> </p>

YYY仅在XXX不在限制标签列表(A,I,B)内时替换XXX

应该在C#regex中以某种方式完成

非常感谢你的帮助:)

2 个答案:

答案 0 :(得分:7)

这已经多次说了,但我可以在这里重复一遍......你真的不想使用正则表达式进行HTML解析。它根本不适合HTML的复杂性(用正则表达式解析它比使用正则表达式更难很多。)

.NET的最佳选择是HTML Agility Pack,它是一个非常强大的库,可以正确解析任何形式的HTML“汤”。操作起来也容易得多,因为它暴露了DOM结构。这将使您能够简单地遍历DOM并轻松检查父/祖先节点,以便可以通过更改适当元素的InnerText属性来执行替换。完成所有操作后,只需从修改后的DOM对象中输出原始HTML即可。

答案 1 :(得分:3)

您可以使用MatchEvaluator。我们的想法是您匹配 列表中某个类型的完整元素目标字符串。如果你匹配一个完整的元素,你只需将其重新插入 - 你不关心它是否包含目标字符串。否则,您插入替换文本。

public string GetReplacement(Match m) {
    return m.Groups[1].Success ? m.Groups[1].Value : "YYY";
}

Regex r = new Regex( @"(?is)(<([abi]\b)[^<>]*>.*?</\2>)|XXX" );
string newString = r.Replace(oldString,
                   new MatchEvaluator(GetReplacement));

但请注意,在许多情况下,即使在有效的(X)HTML中,此代码也会失败。例如,一个元素可以嵌套在同一种类的另一个元素中,如下所示:

<i>blah <i>blah</i> XXX</i>

或者评论中的开头或结尾标记可能会让您失望:

<b>blah <!-- </b> --> XXX</b>

您可以通过使正则表达式和MatchEvaluator代码更复杂来处理许多潜在问题,但最终您要么接受一些缺陷,要么切换到Noldorin推荐的专用HTML解析器。