使用正则表达式在 SAS 中进行电子邮件验证 - 不在一个字段中捕获逗号或多个电子邮件地址



我在SAS中使用以下PERL正则表达式函数来验证电子邮件:

if prxmatch('/^[a-z0-9_.+-]+(.[a-z0-9_+-]+)*@[a-z0-9-]{2,}(.[a-z0-9-]+)*.([a-z]{2,8})/', email) = 1 then prx =1 ;
else prx = 0;

这适用于大多数电子邮件,但在这些情况下,代码无法捕获无效:

some@email.com,(末尾带有逗号)

some@email.com、someother@email.com(一个字符串变量中的两封单独的电子邮件,用逗号分隔)

some@email.com/someother@email.com(一个字符串变量中的两封单独的电子邮件,用/分隔)

这些很容易通过使用 index(epost,',') 来检测,但我发现必须有一种方法将它们包含在 prxmatch 函数中,但我找不到解决方案。正则表达式函数是我发现的,不是我自己写的,虽然我理解了大部分内容,但我找不到正确的语法。

尝试了类似@{1}的东西来表示只允许一个@,但无法确定如何在其中工作。最后还尝试了$/,但这也没有用。

解决方案无疑是用$锚定模式的末尾,就像^锚定开头一样

可以肯定的是,这是您应该拥有的。请尝试并解释您的意思不起作用。您是否有可能尝试将电子邮件字符串与尾随空格或换行符匹配,原始模式会以与忽略虚假逗号相同的方式忽略它们?

我已经分离了模式的分配并使用了/x修饰符,以便可以将无关紧要的空格添加到模式中以分隔其元素并使其更具可读性

pattern = '/ ^ [a-z0-9_.+-]+ ( . [a-z0-9_+-]+ )* @ [a-z0-9-]{2,} ( . [a-z0-9-]+ )* . [a-z]{2,8} $ /x';
if prxmatch(pattern, email) = 1 then prx = 1;
else prx = 0;

如果你可以使用 cpan 中的模块,我建议Email::Valid来验证你的电子邮件地址而不是正则表达式。下面是一个示例:

use Email::Valid;
my @data = qw|some@email.com, some@email.com,someother@email.com some@email.com/someother@email.com|;
foreach my $addy (@data) {
   if (Email::Valid->address($addy)) {
        print "Valid Email $addyn";
   } else {
        print "Invalid email $addyn";
   }
}
__DATA___
Invalid email some@email.com,
Invalid email some@email.com,someother@email.com
Invalid email some@email.com/someother@email.com
$

SAS 中可能很棘手,因为每个 SAS 字符串都有空格填充,除非它恰好是字段的确切最大长度(在这种情况下,如果您将长度设置为正确,这种情况很少见或永远不会)。

因此,您需要:

  1. 在将字符串传递给 prxmatch 之前对其进行修剪(使用 trimstrip 或类似内容)
  2. 告诉您的正则表达式在$之前允许任意数量的空格。

我更喜欢1:

prx_matched = prxmatch(pattern,trim(email));

但是 2 也很好,特别是如果您需要速度:

if prxmatch('/^[a-z0-9_.+-]+(.[a-z0-9_+-]+)*@[a-z0-9-]{2,}(.[a-z0-9-]+)*.([a-z]{2,8})s*$/', email) = 1 then prx =1 ;
else prx = 0;

s是空格元字符,并且匹配空格以外的内容;但是,如果您正确处理输入,则电子邮件验证应该是安全的。


除上述内容外,您还需要将 o 修饰符添加到正则表达式(可能还有 i )。 o阻止 SAS 重新编译静态正则表达式每个数据步进循环(这非常昂贵)。 i意味着您可能也应该使用case insensitive(除非您真的非常确定电子邮件中永远不会有大写字母)。