在JavaScript中检测错误的电子邮件地址

6

我注意到有时用户在联系我们表单中输入错误的电子邮件地址,例如输入@yahho.com、@yhoo.com或@ yahoo.co而不是@ yahoo.com。

我认为可以通过一些JavaScript来纠正这个问题。简单地检查电子邮件地址可能存在的错误,比如上面列出的那些错误,这样如果用户输入his_email@yhoo.com,就可以显示一个非侵入式的消息,或者类似于这样的东西,建议他可能意味着@yahoo.com,并要求他再次检查他输入的电子邮件是否正确。

问题是:
如何在Java Script中检测一个字符串与"yahoo"或"yahoo.com"非常相似?或者一般来说,如何检测两个字符串之间的相似程度?

P.S.(这是一个旁注)在我的特定情况下,用户不是以英语为母语的人,他们中的大多数远非流利,网站本身也不是用英语编写的。

6个回答

12

以下是一个简单的不太理想的实现,可以使用Levenshtein距离来进行一些简单的检查。 "levenshteinenator" 的功劳归功于 这个链接。您需要将您想要检查的流行域名添加到域名数组中,它会检查输入的电子邮件地址的主机部分的距离是否为1或2,这样可以合理地假设有拼写错误。

levenshteinenator = function(a, b) {
    var cost;

    // get values
    var m = a.length;
    var n = b.length;

    // make sure a.length >= b.length to use O(min(n,m)) space, whatever that is
    if (m < n) {
        var c=a;a=b;b=c;
        var o=m;m=n;n=o;
    }

    var r = new Array();
    r[0] = new Array();
    for (var c = 0; c < n+1; c++) {
        r[0][c] = c;
    }

    for (var i = 1; i < m+1; i++) {
        r[i] = new Array();
        r[i][0] = i;
        for (var j = 1; j < n+1; j++) {
            cost = (a.charAt(i-1) == b.charAt(j-1))? 0: 1;
            r[i][j] = minimator(r[i-1][j]+1,r[i][j-1]+1,r[i-1][j-1]+cost);
        }
    }

    return r[m][n];
}

// return the smallest of the three values passed in
minimator = function(x,y,z) {
    if (x < y && x < z) return x;
    if (y < x && y < z) return y;
    return z;
}

var domains = new Array('yahoo.com','google.com','hotmail.com');
var email = 'whatever@yahoo.om';
var parts = email.split('@');
var dist;
for(var x=0; x < domains.length; x++) {
    dist = levenshteinenator(domains[x], parts[1]);
    if(dist == 1 || dist == 2) {
        alert('did you mean ' + domains[x] + '?');
    }
}

6

除了soundex之外,您可能还想看看用于确定Levenshtein距离的算法。


看起来Levenshtein正是我要找的! - hasen

2

这对于一个“联系我们”的表单来说似乎有点大材小用了,不是吗? - Daniel Schaffer
@Daniel,一个简单的Soundex功能可以用不到20行代码编写。但在“联系我们表格”中,几乎“所有东西”都是过度设计了。 :) - Stefan
我想这表明了我的所有“联系我们”表单都是mailto链接...... - Daniel Schaffer

1
当然,作为第一步,您可以剥离域名并进行DNS查找 - 这至少应该告诉您它是否看起来是合法的。

我只需要一个简单的客户端检查,不需要网络连接。 - hasen

0

正如其他人所说,Levenshtein距离是一种可靠的解决方案。

有一个非常优秀的Javascript库可以完全满足您的需求:Mailcheck来自Kicksend。

https://github.com/DimitarChristoff/mailcheck

这个库:

  • 提供域名和顶级域名的建议。
  • 可以定制(域名,顶级域名,字符串距离方法)。
  • 可以与jQuery一起使用
  • 与jQuery解耦

为了速度目的,该库使用sift3字符串相似性算法。据报道,Levenshtein距离产生更好的结果(https://github.com/DimitarChristoff/mailcheck)。


-1

可能可以使用正则表达式,但就我个人而言,编写一个能够获取所有可能的排列组合且不会引起太多误报的正则表达式需要花费太长时间。

所以,这是我会做的:

  • 硬编码一个包含所有常见打字错误的列表。
  • 使用不区分大小写的字符串比较将电子邮件与列表中的每个字符串进行比较。
  • 如果有匹配项,则显示警告 -“您是否想要 yahoo.com?”

是的,它看起来不太美观,但从你的问题中看来,你似乎没有太多要检查的,因此它应该表现得很好。对我来说,这也不像值得花费太多时间的事情,因此这是一个非常简单的解决方案,只需大约15-30分钟即可完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接