Regex - sprawdzanie poprawnosci adresu email

0

Chcę napisać funkcję, która sprawdza poprawność adresu email, znalazłem przykład w Internecie oparty o regex:

#include <regex>
#include <iostream>
#include <string>

bool is_email_valid(const std::string& email)
{
   // define a regular expression
   const std::regex pattern
      ("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+");

   // try to match the string with the regular expression
   return std::regex_match(email, pattern);
}

int main()
{
   std::string email1 = "[email protected]";
   std::string email2 = "[email protected]";
   std::string email3 = "[email protected]";
   std::string email4 = "marius@domain";

   std::cout << email1 << " : " << (is_email_valid(email1) ?
      "valid" : "invalid") << std::endl;
   std::cout << email2 << " : " << (is_email_valid(email2) ?
      "valid" : "invalid") << std::endl;
   std::cout << email3 << " : " << (is_email_valid(email3) ?
     "valid" : "invalid") << std::endl;
   std::cout << email4 << " : " << (is_email_valid(email4) ?
     "valid" : "invalid") << std::endl;

   return 0;
}
 

Niestety po kompilacji dostaje wyjątek: "regex_error", dlaczego to nie działa? Ewentualnie prosiłbym o inne metody sprawdzenia poprawności adresu e-mail, oczywiście mógłbym napisać to "na pałę", ale chciałbym tego uniknąć.

0

Nie powinieneś weryfikować emaila regexem. Polecam lekturę:
http://davidcel.is/blog/2012/09/06/stop-validating-email-addresses-with-regex/
http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html

regex_error to typ, złap wyjątek i napisz co zwraca metoda what(). Napisz też jakiego kompilatora używasz. Wiem, że gcc 4.7 nie miał jeszcze obsługi regexów, nie wiem jak 4.8.

0

@kq dzięki za szybką odpowiedź :) używam gcc 4.7 więc zapewne masz rację z brakiem wsparcia, w takim razie jak najlepiej to zrobić?

0
bool IsValidEmailAddress(std::string address)
{
    static const std::string localPartChars  = "!#$%&'*+-./=?^_`{|}~";
    static const std::string domainPartChars = "-.";

    if(address.find('@') == std::string::npos) return false;

    std::string localPart  = address.substr(0, address.rfind('@'));
    std::string domainPart = address.substr(address.rfind('@') + 1);

    std::string* parts[] = { &localPart, &domainPart };
    for(std::string* part : parts)
    {
        if(part->front() == '(')
        {
            if(part->find(')') == std::string::npos) return false;
            *part = part->substr(part->find(')') + 1);
        }

        if(part->back() == ')')
        {
            if(part->rfind('(') == std::string::npos) return false;
            *part = part->substr(0, part->rfind('('));
        }
    }

    if(localPart.size() > 64 || localPart.size() + domainPart.size() > 255) return false;
    if(localPart.front() == '.' || localPart.back() == '.') return false;
    if(domainPart.front() == '.' || domainPart.back() == '.') return false;

    bool inQuotes = false;
    for(int i = 0; i < localPart.size(); i++)
    {
        if(localPart[i] == '\"')
        {
            if(inQuotes == true)
            {
                if(localPart[i - 1] == '\\') continue;
                if(i != localPart.size() - 1 && localPart[i + 1] != '.') return false;
            }
            else if(i != 0 && localPart[i - 1] != '.') return false;

            inQuotes = !inQuotes;
            continue;
        }

        if(localPart[i] == '.' && localPart[i + 1] == '.') return false;
        if(inQuotes ? !isprint(localPart[i]) :
           (!isalnum(localPart[i]) && localPartChars.find(localPart[i]) == std::string::npos)) return false;
    }

    for(int i = 0; i < domainPart.size(); i++)
    {
        if(domainPart[i] == '.' && domainPart[i + 1] == '.') return false;
        if(!isalnum(domainPart[i]) && domainPartChars.find(domainPart[i]) == std::string::npos) return false;
    }

    return true;
} 

Moim zdaniem powinno być ok...

1 użytkowników online, w tym zalogowanych: 0, gości: 1