在 javascript 中检测错误输入的电子邮件地址

Posted

技术标签:

【中文标题】在 javascript 中检测错误输入的电子邮件地址【英文标题】:detecting mistyped email addresses in javascript 【发布时间】:2010-10-02 09:12:45 【问题描述】:

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

我觉得这可以用一些 javascript 现场纠正。只需检查电子邮件地址是否存在可能的错误,例如上面列出的错误,这样如果用户输入 his_email@yhoo.com,就会显示一条不显眼的消息,或者类似的东西,表明他可能指的是@yahoo。 com,并要求仔细检查他是否正确输入了电子邮件。

问题是: 如何在 java 脚本中检测到字符串与“yahoo”或“yahoo.com”非常相似?或者一般来说,如何检测两个字符串之间的相似度?

附: (这是一个旁注)在我的具体情况下,用户不是以英语为母语的人,而且他们中的大多数人都不流利,网站本身不是英语。

【问题讨论】:

【参考方案1】:

也许可以使用正则表达式,但就我个人而言,写一个我会很满意的正则表达式会花费我太长时间,因为它可以得到所有可能的排列而不会导致太多误报。

所以,这就是我要做的:

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

是的,它不是很漂亮,但看起来(至少从你的问题来看)你需要检查那么多,所以它应该表现得很好。这似乎也不值得(至少在我看来)是值得投入大量时间的事情,所以这是一个令人难以置信的简单解决方案,可以在大约 15-30 分钟内完成。

【讨论】:

【参考方案2】:

查看 soundex 和差异: 如果您使用 ajax,您可以让 sql-server 针对“正确”域检查单词的 soundex-value 并获取建议。也可以制作自己的 soundex 版本(没那么复杂)。

SQL Server's SoundEx function on non-Latin character sets?

Data structure for soundex algorithm?

How do you implement a "Did you mean"?

【讨论】:

“联系我们表格”似乎有点矫枉过正,不是吗? @Daniel,一个简单的 soundex-function 可以在不到 20 行代码中完成。但在“联系我们的表格”中,几乎所有的“一切”都是多余的。 :) 好吧,我想我所有的“联系我们”表格都是 mailto: links...【参考方案3】:

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

【讨论】:

看来 Levenshtein 就是我所追求的!【参考方案4】:

当然,作为第一步,您可以去掉域名并进行 DNS 查找 - 这至少应该告诉您它是否合法。

【讨论】:

我只想要一个简单的客户端检查,没有网络连接。【参考方案5】:

这是一个肮脏的实现,可以让您使用Levenshtein distance 进行一些简单的检查。 “levenshteinenator”的功劳归于this link。您可以将您想要的任何流行域添加到域数组中,它会检查输入的电子邮件的主机部分的距离是 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】:

正如其他人所说,Levenshtein distance 是一个可靠的解决方案。

有一个出色的 Javascript 库可以完全满足您的需求:来自 Kicksend 的 Mailcheck

https://github.com/DimitarChristoff/mailcheck

图书馆:

为域和***域提供建议。 可自定义(域、***域、字符串距离法)。 可以和jQuery一起使用 与jQuery解耦

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

【讨论】:

以上是关于在 javascript 中检测错误输入的电子邮件地址的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript - 简单数据验证中的错误逻辑

使用纯javascript检测更改的输入文本框[重复]

如何使用 javascript 检测表情符号

如何使用 javascript 检测表情符号

检测输入字段值的重复

在javascript中使用时正则表达式无效组错误