验证电子邮件地址而不使用正则表达式

时间:2016-01-15 11:29:37

标签: c++ c++11 winapi boost mfc

这个必须有一个规范的答案,但我找不到它...... Using a regular expression to validate an email address的答案显示正则表达式真的不是验证电子邮件的最佳方法。在线搜索不断提出大量基于正则表达式的答案。

这个问题是关于PHP的,答案引用了一个方便的类MailAddress。 C#有一些非常类似但是普通的旧C ++呢?是否有一个boost / C ++ 11实用工具可以消除所有的痛苦?甚至是WinAPI / MFC中的某些东西?

1 个答案:

答案 0 :(得分:0)

我必须编写一个解决方案,因为我安装的g ++版本不支持std :: regex(应用程序崩溃),我不想升级单个电子邮件验证的东西,因为这个应用程序可能永远不需要任何进一步的正则表达式我写了一个功能完成这项工作。您甚至可以轻松地缩放电子邮件地址的每个部分(在@之前,之后和之后的#39;。)之后,根据您的需要缩放允许的字符。花了20分钟编写,然后更简单,然后只为一个函数调用搞乱编译器和环境。

你走了,玩得开心:

bool emailAddressIsValid(std::string _email)
{
    bool retVal = false;

    //Tolower cast
    std::transform(_email.begin(), _email.end(), _email.begin(), ::tolower);

    //Edit these to change valid characters you want to be supported to be valid. You can edit it for each section. Remember to edit the array size in the for-loops below.

    const char* validCharsName = "abcdefghijklmnopqrstuvwxyz0123456789.%+_-"; //length = 41, change in loop
    const char* validCharsDomain = "abcdefghijklmnopqrstuvwxyz0123456789.-"; //length = 38, changein loop
    const char* validCharsTld = "abcdefghijklmnopqrstuvwxyz"; //length = 26, change in loop

    bool invalidCharacterFound = false;
    bool atFound = false;
    bool dotAfterAtFound = false;
    uint16_t letterCountBeforeAt = 0;
    uint16_t letterCountAfterAt = 0;
    uint16_t letterCountAfterDot = 0;

    for (uint16_t i = 0; i < _email.length(); i++) {
        char currentLetter = _email[i];

        //Found first @? Lets mark that and continue
        if (atFound == false && dotAfterAtFound == false && currentLetter == '@') {
            atFound = true;
            continue;
        }

        //Found '.' after @? lets mark that and continue
        if (atFound == true && dotAfterAtFound == false && currentLetter == '.') {
            dotAfterAtFound = true;
            continue;
        }

        //Count characters before @ (must be > 0)
        if (atFound == false && dotAfterAtFound == false) {
            letterCountBeforeAt++;
        }

        //Count characters after @ (must be > 0)
        if (atFound == true && dotAfterAtFound == false) {
            letterCountAfterAt++;
        }

        //Count characters after '.'(dot) after @ (must be between 2 and 6 characters (.tld)
        if (atFound == true && dotAfterAtFound == true) {
            letterCountAfterDot++;
        }

        //Validate characters, before '@'
        if (atFound == false && dotAfterAtFound == false) {
            bool isValidCharacter = false;
            for (uint16_t j = 0; j < 41; j++) {
                if (validCharsName[j] == currentLetter) {
                    isValidCharacter = true;
                    break;
                }
            }
            if (isValidCharacter == false) {
                invalidCharacterFound = true;
                break;
            }
        }

        //Validate characters, after '@', before '.' (dot)
        if (atFound == true && dotAfterAtFound == false) {
            bool isValidCharacter = false;
            for (uint16_t k = 0; k < 38; k++) {
                if (validCharsDomain[k] == currentLetter) {
                    isValidCharacter = true;
                    break;
                }
            }
            if (isValidCharacter == false) {
                invalidCharacterFound = true;
                break;
            }
        }

        //After '.' (dot), and after '@' (.tld)
        if (atFound == true && dotAfterAtFound == true) {
            bool isValidCharacter = false;
            for (uint16_t m = 0; m < 26; m++) {
                if (validCharsTld[m] == currentLetter) {
                    isValidCharacter = true;
                    break;
                }
            }
            if (isValidCharacter == false) {
                invalidCharacterFound = true;
                break;
            }
        }

        //Break the loop to speed up thigns if one character was invalid
        if (invalidCharacterFound == true) {
            break;
        }
    }

    //Compare collected information and finalize validation. If all matches: retVal -> true!
    if (atFound == true && dotAfterAtFound == true && invalidCharacterFound == false && letterCountBeforeAt >= 1 && letterCountAfterAt >= 1 && letterCountAfterDot >= 2 && letterCountAfterDot <= 6) {
        retVal = true;
    }

    return retVal;
}