电子邮件地址的正则表达式

I working for hours on this code. I want to handle those mail addresses in a regex code:

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

Could you please provide something for me? I ended up with: [-0-9a-zA-Z.+_]+(@|\(@\)|at)+[-0-9a-zA-Z.+_]+\.(de|com|net|org)

But it's not working :(

You can modify your pattern like this:

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

Demo: http://regex101.com/r/vY0rD6/1

What i would do is the following:

Create an interface for email matching:

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

Then implement every currently known possibilities:

//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;
    }
}

And another:

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.
    }
}

Then where you validate, simply create an array of all the matchers:

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

This way it is extensible, clear, and easy to understand, if you need to add more of these (or need to remove one later), but possibly a bit slower.

Also could use conditionals: See 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';

Used x (PCRE_EXTENDED) modifier for the commenting.

Test at eval.in / SO Regex FAQ