【问题标题】:Regex expression for mail address邮件地址的正则表达式
【发布时间】:2014-08-27 10:54:25
【问题描述】:

我在这段代码上工作了几个小时。我想在正则表达式代码中处理这些邮件地址:

text@text(Dot)de
text(@)text(Dot)de
text(at)text(Dot)de
text|at|text(Dot)de

text@text.de
text(@)text.de
text(at)text.de
text|at|text.de

text @ text.de
text (@) text.de
text (at) text.de
text |at| text.de

你能为我提供一些东西吗?我最终得到:[-0-9a-zA-Z.+_]+(@|\(@\)|at)+[-0-9a-zA-Z.+_]+\.(de|com|net|org)

但它不起作用:(

【问题讨论】:

  • 如果太复杂,为什么不为每个可能的版本创建一个正则表达式,循环它们,如果其中任何一个匹配,你可以接受它。记录和修改更容易,因为看起来可能会有更多这些“隐藏”的电子邮件格式,将来可能需要这些格式。
  • /[-0-9a-zA-Z.+_]+\s*((@|at)|\((@|at)\)|\|(@|at)\|)\s*[-0-9a-zA-Z.+_]+(\.|\(dot\))(de|com|net|org)/ig(匹配所有样本,但谁知道还有什么。首先不推荐这个一般概念。)
  • 中间部分可以匹配(?:\|at\||\(at\)|\(@\)|@)
  • 对于php你应该考虑使用filter_var函数php.net/filter_var

标签: php html regex


【解决方案1】:

我会做以下事情:

为邮件匹配创建接口:

interface IEmailMatcher {
    function matches($rawEmail);
    function toEmail($rawEmail);
}

然后实现所有当前已知的可能性:

//Matcher for regular emails
class BasicEmailMatcher implements IEmailMatcher {
    public function matches($rawEmail) {
        // PHP has a built in for this
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }

    public function toEmail($rawEmail) {
        // If we passed the filter, it doesn't need any transformation.
        return $rawEmail;
    }
}

还有一个:

class OtherEmailMatcher implements IEmailMatcher {
    public function matches($rawEmail) {
        return preg_match(/*pattern for one format*/, $rawEmail);
    }

    public function toEmail($rawEmail) {
        // return the funky looking email transformed to normal email.
    }
}

然后在您验证的地方,只需创建一个包含所有匹配器的数组:

$matchers = [new BasicEmailMatcher(), new OtherEmailMatcher(), ...];
foreach($matchers as $matcher) {
    if($matcher->matches($inputEmail)){
        // format it back to normal.
        $email = $matcher->toEmail($inputEmail); 
    }
}

如果您需要添加更多这些(或需要删除稍后),但可能会慢一些。

【讨论】:

    【解决方案2】:

    你可以像这样修改你的模式:

    /([\-0-9a-zA-Z\.\+_]+\s?(?:@|\(at\)|\|at\||\(@\))\s?+[\-0-9a-zA-Z\.\+_]+(?:\.|\(Dot\))(?:de|com|net|org))/g
    

    演示:http://regex101.com/r/vY0rD6/1

    【讨论】:

      【解决方案3】:

      也可以使用conditionals:见example at regex101

      $pattern = '~
      [-+.\w]+                # [-0-9a-zA-Z.+_]+
      (\s*)                   # optional: any amount of spaces (-> $1)
      (?:(\()|(\|))?          # conditional $2: if opening ( | $3: if |
      (@|at)                  # @|at  
      (?(2)\)|(?(3)\|))       # if $2 -> ), if $3 -> | 
      \1                      # amount of spaces, captured in $1
      [-+.\w]+
      (?:\.|\(Dot\))(?:de|com|net|org)~x';
      

      使用x (PCRE_EXTENDED) modifier 进行评论。

      Test at eval.in/SO Regex FAQ

      【讨论】:

        猜你喜欢
        • 2014-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-25
        • 2011-10-14
        • 1970-01-01
        相关资源
        最近更新 更多