6

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

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

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

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

4

6 回答 6

11

这是一个肮脏的实现,可以让你使用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] + '?');
    }
}
于 2009-01-20T04:03:09.050 回答
6

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

于 2009-01-20T03:54:15.153 回答
2

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

SQL Server 对非拉丁字符集的 SoundEx 函数?

soundex算法的数据结构?

你如何实现“你的意思是”?

于 2009-01-20T03:52:40.023 回答
1

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

于 2009-01-20T03:56:51.107 回答
0

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

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

https://github.com/DimitarChristoff/mailcheck

图书馆:

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

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

于 2014-03-31T18:32:59.647 回答
-1

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

所以,这就是我要做的:

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

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

于 2009-01-20T03:52:33.503 回答