使用正则表达式检测文本中的电子邮件

时间:2012-01-19 12:50:39

标签: c# .net regex

我想以文本格式检测电子邮件,以便我可以在锚点上使用mailto标记在其上放置锚标记。我有正则表达式,但代码还检测已经由锚标记封装或在锚标记mailto参数内的电子邮件。

我的正则表达式是:

([\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?)

但它在以下示例文本中检测到3个匹配项:

ttt <a href='mailto:someone@example.com'>someemail@mail.com</a> abc email@email.com

我希望只有email@email.com与正则表达式匹配。

2 个答案:

答案 0 :(得分:2)

与我的previous answer非常类似于您的其他问题,请尝试此

(?<!(?:href=['"]mailto:|<a[^>]*>))(\b[\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?)

唯一真正不同的是电子邮件开始前的单词边界\b

看到一个类似的表达式here on Regexr,它不完全相同,因为Regexr不支持外观中的交替和无限长度。

答案 1 :(得分:2)

最好将HTML解析为适合的内容(例如HtmlAgilityPack),并将其与正则表达式结合以更新文本节点:

    string sContent = "ttt <a href='mailto:someone@example.com'>someemail@mail.com</a> abc email@email.com";
    string sRegex = @"([\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?)";
    Regex Regx = new Regex(sRegex, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);

    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
    doc.LoadHtml(sContent);

    var nodes = doc.DocumentNode.SelectNodes("//text()[not(ancestor::a)]");
    foreach (var node in nodes)
    {
        node.InnerHtml = Regx.Replace(node.InnerHtml, @"<a href=""mailto:$0"">$0</a>");
    }
    string fixedContent = doc.DocumentNode.OuterHtml;

我注意到您发布了同样的问题other forums as well,但没有在其中任何一个中指定答案。