我正在为blogengine.net编写一个自动链接扩展程序,它会自动将博客帖子中的关键短语链接到特定网址。我发现的问题通常是自动链接的短语列表是彼此的子集,例如“bmw”是“宝马汽车租赁”的子集,所以如果我使用正则表达式自动链接“宝马汽车租赁”然后自动链接短语“bmw”,前者已经自动链接。优先权很重要,较长的短语必须首先自动链接,然后是较小的短语,可能是较长的短语的子集。
我需要的是一个正则表达式,如果它已经在一个锚标记内,将解除匹配,即我的短语应该被解雇。
我不必经常使用正则表达式,所以我不是完全不喜欢它们,到目前为止我已经设法将一个匹配锚标签的正则表达式组合在一起,但不是反过来这是什么我需要。例如<a\b[^>]*>stuff(.*?)</a>
非常欢迎任何建议和意见。
增加并希望最终的解决方案....只有时间会告诉: - 经过一些试验和错误后,我使用的最终正则表达式如下。这基于我标记为答案的解决方案: -
(?<!<a [^<]+)(?<!<img [^<]+)(?<=[ ,.;!]+)search phrase goes here(?=[ ,.;&!]+)(?!!.*<\\a>)
它允许匹配的文本在空格和基本标点符号之前和之后,并允许编码字符,如非空格
等。它还避免匹配img标记中的任何内容。
我意识到它仍然不是100%,但就要求而言,它就足够了。
感谢大家的帮助和意见。
答案 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, 签字。