正则表达式,如果它是html锚标记中的文本,则与字符串不匹配

时间:2011-03-20 23:41:54

标签: .net regex

我正在为blogengine.net编写一个自动链接扩展程序,它会自动将博客帖子中的关键短语链接到特定网址。我发现的问题通常是自动链接的短语列表是彼此的子集,例如“bmw”是“宝马汽车租赁”的子集,所以如果我使用正则表达式自动链接“宝马汽车租赁”然后自动链接短语“bmw”,前者已经自动链接。优先权很重要,较长的短语必须首先自动链接,然后是较小的短语,可能是较长的短语的子集。

我需要的是一个正则表达式,如果它已经在一个锚标记内,将解除匹配,即我的短语应该被解雇。

我不必经常使用正则表达式,所以我不是完全不喜欢它们,到目前为止我已经设法将一个匹配锚标签的正则表达式组合在一起,但不是反过来这是什么我需要。例如<a\b[^>]*>stuff(.*?)</a>

非常欢迎任何建议和意见。

增加并希望最终的解决方案....只有时间会告诉: - 经过一些试验和错误后,我使用的最终正则表达式如下。这基于我标记为答案的解决方案: -

(?<!<a [^<]+)(?<!<img [^<]+)(?<=[ ,.;!]+)search phrase goes here(?=[ ,.;&!]+)(?!!.*<\\a>)

它允许匹配的文本在空格和基本标点符号之前和之后,并允许编码字符,如非空格&nbsp;等。它还避免匹配img标记中的任何内容。 我意识到它仍然不是100%,但就要求而言,它就足够了。

感谢大家的帮助和意见。

2 个答案:

答案 0 :(得分:1)

负面的后视和前瞻有助于在这种情况下,以下匹配something只有在它没有(lookbehind)之前:

(?<!<a>)something

然而,正如之前在SO上多次指出的那样,正则表达式不是解析HTML的最佳工具,它们用于词法分析,而不是解析。有关详细信息,请查看问题第一条评论中链接的question

答案 1 :(得分:1)

诀窍是使用非贪婪的lookbehind,然后为锚元素的结尾添加一个前瞻。我发现使用像Expresso这样的工具可以更容易地创建这种正则表达式。

var text = "Final report of the commercial starship Nostromo, third officer reporting. The other members of the crew, Kane, Lambert, Parker, Brett, Ash and Captain Dallas, are dead. Cargo and ship destroyed. I should reach the frontier in about six weeks. With a little luck, the network will pick me up. This is Ripley, last survivor of the Nostromo, signing off.";
var phrases = new List<KeyValuePair<string, string>> { 
    new KeyValuePair<string,string>("Nostromo", "http://www.imdb.com/media/rm3374159872/tt0078748"),
    new KeyValuePair<string,string>("starship Nostromo", "http://en.wikipedia.org/wiki/Alien_%28film%29#Spaceships_and_planets")};

foreach (var phrase in phrases.OrderByDescending(kv => kv.Key.Length))
{ 
    text = new Regex("(?<!<a [^<]+)" + phrase.Key + "(?!!.*<\\a>)").
                    Replace(text, "<a href=\"" + 
                                    phrase.Value + "\">" + 
                                    phrase.Key + "</a>");
}

结果:

  

商业广告的最终报道   {3}},第三官员报告。   其他船员,凯恩,   Lambert,Parker,Brett,Ash和   达拉斯船长已经死了。货物和   船毁了。我应该达到   大约六个星期前沿。有了   运气不好,网络会接我   起来。这是里普利,最后的幸存者   starship Nostromo,   签字。