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

时间:2012-01-18 13:00:57

标签: c# .net regex

我在C#中有一个正则表达式来检测文本中的电子邮件,然后我在其中放入一个带有mailto参数的锚标记,以使其可以点击。但是,如果电子邮件已经在锚标记中,则正则表达式会检测锚标记中的电子邮件,然后下一个代码会在其上添加另一个锚标记。 Regex有没有办法避免已经在锚标签中的电子邮件?

C#中的正则表达式代码是:

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);

,示例文本为:

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

,所需的输出是:

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

所以,这里的重点是Regex应该只检测那些不在锚标签内或已经可点击的有效电子邮件,并且它们都不应该是锚标签中锚标记的href值。

上面给出的Regex正在检测文本中不需要的每个可能的电子邮件。

1 个答案:

答案 0 :(得分:4)

你可以使用负面看来测试mailto:

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

应匹配前面没有mailto:

的任何内容

我认为正在发生的事情是.中的([\w\-]+(.[\w-])+)匹配太多了。您的意思是使用.而不是\.吗?

通过转义.以下代码生成

someemail@mail.com
email@email.com


public void Test()
{

    Regex pattern = new Regex(@"\b(?<!mailto:)([\w\-]+(\.[\w\-])*@([a-z0-9-]+(.[a-z0-9-]+)?.[a-z]{2,6}|(\d{1,3}.){3}\d{1,3})(:\d{4})?)");
    MatchCollection matchCollection = pattern.Matches("ttt <a href='mailto:someone@example.com'>someemail@mail.com</a> abc email@email.com");
    foreach (Match match in matchCollection)
    {
        Debug.WriteLine(match);
    }
}

您尝试做的事情的现实实施可能看起来更像

Regex pattern = new Regex(@"(?<!mailto\:)\b[\w\-]+@[a-z0-9-]+(\.[a-z0-9\-])*\.[a-z]{2,8}\b(?!\<\/a)");
MatchCollection matchCollection = pattern.Matches("ttt <a href='mailto:so1meone@example.com'>someemail@mail.com</a> abc email@email.com");
foreach (Match match in matchCollection)
{
    Debug.WriteLine(match);
}

对不起,你是对的,我没有认为否定的断言不够贪婪。

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

应该有效