Web应用中一种用户友好Email验证模式

每过一段时间,我的网站和论坛就会出现注册邮件错误问题。而且往往是缺少某个字符这样的错误。例如:hotmail.com写成了hotmai.com 对于这种意图明确但又不容易发现的错误,普通邮件格式验证函数是无法处理的。因为这种拼写错误依然属于合法邮件地址。但是一个友好的Web页面应该给与用户适当的提示。这里我提出一个容易想到的简单方法处理这个问题。

我们计算用户输入的邮件域和一些常见邮件域的 Levenshtein Distance,也称作字符串编辑距离,是指从一个字符串转换到另一个字符串最小的编辑操作次数。对于LD足够小但又不为0的情况,给于用户提示。

下面给出Levenshtein Distance的js实现代码:

function levenshtein(a, b) {
    var i;
    var j;
    var cost;
    var d = new Array();

    if (a.length == 0) {
        return b.length;
    }

    if (b.length == 0) {
        return a.length;
    }

    for (i = 0; i <= a.length; i++) {
        d[i] = new Array();
        d[i][0] = i;
    }

    for (j = 0; j <= b.length; j++) {
        d[0][j] = j;
    }

    for (i = 1; i <= a.length; i++) {
        for (j = 1; j <= b.length; j++) {

            cost = (a.charAt(i - 1) == b.charAt(j - 1)) ? 0 : 1;

            d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);

            if (i > 1 && j > 1 &&
              a.charAt(i - 1) == b.charAt(j - 2) &&
              a.charAt(i - 2) == b.charAt(j - 1)) {
                d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + cost)
            }
        }
    }
    return d[a.length][b.length];
}

接下来我们要准备一些常用的邮件域信息:

function checkCommonMail(id,errorid) {
    var email = document.getElementById(id).value;
    var useremailDomain=email.substring(email.indexOf("@")+1).toLowerCase();
    var error=document.getElementById(errorid);

    var commonDomain = [
        "hotmail.com",
        "gmail.com",
        ["yahoo.cn","yahoo.hk","yahoo.com.cn","yahoo.com.hk","yahoo.com"],
        "163.com",
        "sina.com",
        "live.com",
        "qq.com",
        "vip.qq.com"];

    for(var i=0;i

上面的函数中yahoo域为并列结算,这样计算更符合用户的意图。

该方式适用处理用户无意间输入的错误。当然你可以同时配合邮箱格式验证函数,来过滤掉一些完全错误的邮箱输入:

function checkMail(id) {
    var email = document.getElementById(id).value;
    var pattern = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
    if (pattern.test(email)) {
        return true;
    } else {
        return false;
    }
}

最后加一句题外话。作为一个普通的程序员,应该能够合理的应用上述功能函数。但是作为一个优秀的程序员,应该能理解上述函数算法。通过阅读上面levenshtein函数,优秀的程序员应该立即识别出这是一个典型的动态规划算法,哪里是动态转移方程,时间复杂度大概是什么等等。