正则表达式 - 将电子邮件地址与例外匹配

时间:2017-04-26 09:10:17

标签: c# regex pattern-matching

请仔细阅读问题,这与验证电子邮件地址无关!

我正在尝试构建一个正则表达式(当前在C#中),它从文本中提取所有电子邮件地址,但有两个特殊例外。

我得到了:

  • user1@company.com
  • user2@company.com
  • user3@company.com
  • user1@private.com
  • user2@private.com

所有在同一行的同一文本文件中,由空格字符分隔。

首先,我尝试匹配所有这些电子邮件地址,但以“user1”开头的地址除外。我用过:

[\S]*(?<!user1)@[\S]*\..[a-zA-Z.]{1,}

运作良好。现在我有另一个要求sais:如果完整的电子邮件地址与“user2@private.com”匹配,也不匹配。所以它应匹配“user2@company.com”,因此我不能使用:

[\S]*(?<!(user1|user2))@[\S]*\..[a-zA-Z.]{1,}

因此我尝试了额外的负面看法:

([\S]*(?<!user1)@[\S]*\..[a-zA-Z.]{1,})(?<!user2@private\.com)

哪个不起作用,因为它似乎满足于匹配“user2@private.co”我猜。有没有办法实现我想做的事情?我的头已经疼,......

我会使用额外的代码,但是因为我使用的第三方软件只给了我正则表达式的选项,而且只有一个正则表达式的选项,这就是我所拥有的,... < / p>

2 个答案:

答案 0 :(得分:2)

一个看起来不太好的单一正则表达式解决方案是

(?<!\S)(?!user1@|user2@private\.com(?!\S))\S+@\S+\.[a-zA-Z]{2,}(?!\S)

请参阅regex demo

详细

  • (?<!\S) - 一个前面没有非空白字符的位置
  • (?!user1@|user2@private\.com(?!\S)) - user1@user2@private.com未跟随非空格字符
  • ,无法跟踪该位置
  • \S+ - 1+非空白
  • @ - 文字@
  • \S+ - 1+非空白
  • \. - 一个点
  • [a-zA-Z]{2,}(?!\S) - 2个或更多ASCII字母后面没有非空白字符。

更易读的方法是使用空格分割,获取与@"^\S+@\S+\.\S+$"匹配的项目并使用一些代码来过滤掉不需要的匹配项:

var s = @"Text user1@company.com here user2@company.com and user3@company.com here user1@private.com more user2@private.com";
var result = s.Split().Where(m => 
        Regex.IsMatch(m, @"^\S+@\S+\.\S+$") && m != "user2@private.com" && !m.StartsWith("user1@"));
foreach (var str in result)
    Console.WriteLine(str);
// => user2@company.com, user3@company.com

请参阅C# demo

答案 1 :(得分:1)

你应该可以使用负向前看。如果您需要过滤掉明确的电子邮件,则以下解决方案应该有效。但请记住,它不是完全可扩展的。您不希望在此处应用数千封电子邮件。

^(?!user1|user2(?!@company.com))[\S]*@[\S]*\..[a-zA-Z.]{1,}

如果您怀疑这些规则中的许多规则可以在将来适用,那么您可能需要考虑更好的方法。如果要过滤掉的电子邮件是明确的(不是模式),那么您可以在某处保留黑名单,并在提取/验证电子邮件地址模式后将其过滤掉。