1

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 :(

kero
  • 10,389
  • 5
  • 38
  • 47
  • http://stackoverflow.com/a/719543/213464 – YOU Aug 27 '14 at 10:58
  • 1
    If it's too complicated, why not just create a regex for each of the possible versions, loop over them, and if any of them matches, you can accept it. It's easier to document and modify, because it looks like, there could be much more of these "hidden" email formats, that might be required in the future. – Balázs Édes Aug 27 '14 at 11:00
  • `/[-0-9a-zA-Z.+_]+\s*((@|at)|\((@|at)\)|\|(@|at)\|)\s*[-0-9a-zA-Z.+_]+(\.|\(dot\))(de|com|net|org)/ig` (Matches all the samples, but who knows what else. Would't recommend this general concept in the first place.) – Biffen Aug 27 '14 at 11:00
  • for middle part, you can match with `(?:\|at\||\(at\)|\(@\)|@)` – YOU Aug 27 '14 at 11:01
  • for php you should consider using the filter_var function http://php.net/filter_var – jvecsei Aug 27 '14 at 11:11

3 Answers3

3

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.

Balázs Édes
  • 12,013
  • 4
  • 45
  • 79
1

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

lpg
  • 4,784
  • 1
  • 13
  • 15
1

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

Community
  • 1
  • 1
Jonny 5
  • 11,051
  • 2
  • 20
  • 42