обнаружение опечаток адресов электронной почты в JavaScript - PullRequest
4 голосов
/ 20 января 2009

Я иногда замечаю, что пользователи неправильно набирают свой адрес электронной почты (в форме для связи с нами), например, набирая @ yahho.com, @ yhoo.com или @ yahoo.co вместо @ yahoo.com

Я чувствую, что это можно исправить на месте с помощью некоторого JavaScript. Просто проверьте адрес электронной почты на наличие возможных ошибок, таких как перечисленные выше, чтобы, если пользователь вводит his_email@yhoo.com, можно было отображать ненавязчивое сообщение или что-то в этом роде, предполагая, что он, вероятно, означает @yahoo. com, и с просьбой перепроверить, он набрал свою электронную почту правильно.

Вопрос:
Как я могу определить - в java-скрипте - что строка очень похожа на "yahoo" или "yahoo.com"? или вообще, как я могу определить уровень сходства между двумя строками?

P.S. (это примечание) В моем конкретном случае пользователи не являются носителями английского языка, и большинство из них не очень хорошо владеют языком, сам сайт не на английском языке.

Ответы [ 6 ]

9 голосов
/ 20 января 2009

Вот грязная реализация, которая может получить некоторые простые проверки с использованием Levenshtein distance. Кредит на «левенштейненатор» идет на 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 голосов
/ 20 января 2009

В дополнение к soundex вы также можете взглянуть на алгоритмы определения Левенштейна расстояния.

2 голосов
/ 20 января 2009

Проверьте Soundex и разницу: Если вы используете ajax, у вас может быть sql-сервер, проверяющий soundex-значение слов в отношении «правильных» доменов и получающий предложения обратно. Также возможно сделать собственную версию soundex (это не так сложно).

Функция SQLEx для SoundEx для нелатинских наборов символов?

Структура данных для алгоритма soundex?

Как вы реализуете «Вы имели в виду»?

1 голос
/ 20 января 2009

Конечно, в качестве первого шага вы можете удалить доменное имя и выполнить поиск DNS - это должно по крайней мере сказать вам, если оно кажется законным.

0 голосов
/ 31 марта 2014

Как уже говорилось, расстояние Левенштейна - верное решение.

Существует отличная библиотека Javascript, которая делает именно то, что вы хотите: Mailcheck от Kicksend.

https://github.com/DimitarChristoff/mailcheck

Библиотека:

  • предлагает предложения для доменов и доменов верхнего уровня.
  • можно настроить (домены, топовые домены, метод расстояния до строки).
  • можно использовать с jQuery
  • отделен от jQuery

Эта библиотека использует алгоритм сходства строк sift3 для целей скорости. Сообщалось, что расстояние Левенштейна дает лучшие результаты (https://github.com/DimitarChristoff/mailcheck).

0 голосов
/ 20 января 2009

Можно было бы использовать регулярное выражение, но лично мне потребовалось бы слишком много времени, чтобы написать такое, которым я был бы доволен, который мог бы получить все возможные варианты, не вызывая слишком много ложных срабатываний.

Итак, вот что я бы сделал:

  • Жесткий код списка всех распространенных ошибок при печати. ​​
  • Используйте сравнение строк без учета регистра, чтобы сравнить электронную почту с каждой строкой в ​​списке.
  • Если есть совпадение, выведите предупреждение - «Вы имели в виду yahoo.com?"

Да, это не очень красиво, но не кажется (по крайней мере, из вашего вопроса), что у вас будет столько проверок, поэтому он должен работать просто отлично. Это также не кажется (по крайней мере, мне) чем-то, на что стоит потратить много времени, так что это невероятно простое решение, которое можно сделать за 15-30 минут.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...