c++ - 在没有正则表达式的情况下验证电子邮件地址

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

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

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

最佳答案

我必须编写一个解决方案,因为我安装了一个不支持 std::regex 的 g++ 版本(应用程序崩溃),而且我不想为单个电子邮件验证升级这个东西,因为这个应用程序可能永远不需要任何进一步的正则表达式我写了一个函数来完成这项工作。您甚至可以根据需要轻松地为电子邮件地址的每个部分(@ 之前、@ 之后和'.' 之后)缩放允许的字符。花了 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;
}

关于c++ - 在没有正则表达式的情况下验证电子邮件地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34810070/

相关文章:

C++ 使用线程作为定时器

c++ - 使用 char[] 创建字符串

c++ - 如何知道自己在windows下是否有管理员权限?

winapi - 如何在MFC中捕获WM_SHOWWINDOW命令

Delphi - 获取应用程序打开了哪些文件

c++ - 如何使用 std::array 构造函数参数 C++ 列表初始化 const std::array 成员

c++ - 是否建议使用 extern 来避免 header 依赖?

c++ - Clang (OS X) 在特定的嵌套声明中需要 "template"关键字,而 VS 禁止它

C++:如何创建一个临时对象,包含一个指针 - const 或非常量,具体取决于上下文?

c++ - 从元组中提取多种类型