Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Нормализация ФИО (https://javascript.ru/forum/project/67218-normalizaciya-fio.html)

psiklop 04.02.2017 00:00

Нормализация ФИО
 
Вот написал такую функцию, особо не заморачивался, может кто улучшит.
Так как пользователи пишут фио, то капслоком, то наоборот без заглавных букв, то в неправильном порядке.
Функция не проверяет на валидность - она исправляет, проверять надо после нее.
Простая функция, но эффект достаточно занимательный, я считаю такая должна быть в каждой форме.

function fiofix(param) {
var str = [];
var temp;
var v = param.trim();
function fioporyadok(a,b) {
var f = ["ов","ова","ин","ина","ко"];
var o = ["ич","вна"];
for (var i = 0; i < f.length; i++) {
if (a.lastIndexOf(f[i]) == a.length-f[i].length) return -1;
if (b.lastIndexOf(f[i]) == b.length-f[i].length) return 1;}
for (var i = 0; i < o.length; i++) {
if (a.lastIndexOf(o[i]) == a.length-o[i].length) return 1;
if (b.lastIndexOf(o[i]) == b.length-o[i].length) return -1;}
return 0;}
v = v.replace(/^-*/, '');
v = v.replace(/-{2,}/g, '-');
v = v.replace(/\s{2,}/g, ' ');
v = v.replace(/\s*-\s*/g, '-');
if (v == "") return;
v = v.split(" ");
v.forEach(function(i) {
i = i.trim();
if (i == "") return;
temp = i[0].toUpperCase();
temp += i.substr(1).toLowerCase();
str.push(temp);
});
str.sort(fioporyadok);
v = str.join(" ");
str = [];
v = v.split("-");
v.forEach(function(i) {
temp = i[0].toUpperCase();
temp += i.substr(1);
str.push(temp);
});
return str.join("-");}

alert(fiofix("сергеевна ИРИНА карпова"));

рони 04.02.2017 01:29

psiklop,
предположим не карпова а карпенко?

function fiofix(param) {
var str = [];
var temp;
var v = param.trim();
function fioporyadok(a,b) {
var f = ["ов","ова","ин","ина","ко"];
var o = ["ич","вна"];
for (var i = 0; i < f.length; i++) {
if (a.lastIndexOf(f[i]) == a.length-f[i].length) return -1;
if (b.lastIndexOf(f[i]) == b.length-f[i].length) return 1;}
for (var i = 0; i < o.length; i++) {
if (a.lastIndexOf(o[i]) == a.length-o[i].length) return 1;
if (b.lastIndexOf(o[i]) == b.length-o[i].length) return -1;}
return 0;}
v = v.replace(/^-*/, '');
v = v.replace(/-{2,}/g, '-');
v = v.replace(/\s{2,}/g, ' ');
v = v.replace(/\s*-\s*/g, '-');
if (v == "") return;
v = v.split(" ");
v.forEach(function(i) {
i = i.trim();
if (i == "") return;
temp = i[0].toUpperCase();
temp += i.substr(1).toLowerCase();
str.push(temp);
});
str.sort(fioporyadok);
v = str.join(" ");
str = [];
v = v.split("-");
v.forEach(function(i) {
temp = i[0].toUpperCase();
temp += i.substr(1);
str.push(temp);
});
return str.join("-");}

alert(fiofix("сергеевна ИРИНА карпенко"));

psiklop 04.02.2017 04:56

все дело в массиве f и o
думаю его можно улучшить так
var f = ["ов","ова","ко","ский","ская","ин","ина"];
var o = ["евич","евна"];


у тебя не вышло знаешь почему, потому как ирина кончается на 'ина',
так может заканчиваться и женская фамилия
если в массиве 'ко' поставить перед 'ина' все будет как надо
идеально конечно наверняка не будет, но все таки

на самом деле дофига женских имен кончается на 'ина' поэтому надо поставить в самый конец массива

Vlasenko Fedor 04.02.2017 05:23

Может стоит воспользоваться готовым решением https://dadata.ru/

psiklop 04.02.2017 05:47

Цитата:

Сообщение от Poznakomlus (Сообщение 443141)
Может стоит воспользоваться готовым решением https://dadata.ru/

фигасе ты очканул, ну плати за нормализацию если хочешь, а я обойдусь своей функцией, ну платить за нормализацию адреса еще соглашусь, но платить за такую ерунду как фио

в общем я подозреваю что функция может и вред принести если не русские, так что улучшений дофига можно править или сортировку можно вообще закоментировать

Vlasenko Fedor 04.02.2017 13:24

Цитата:

Сообщение от psiklop
ну плати за нормализацию если хочешь

http://joxi.ru/eAO79GkixvO9EA
Вам должно хватить бесплатного сервиса

psiklop 04.02.2017 14:35

Цитата:

Сообщение от Poznakomlus (Сообщение 443235)
http://joxi.ru/eAO79GkixvO9EA
Вам должно хватить бесплатного сервиса

нет, не должно, нужна просто нормализация подсказок не надо

ksa 06.02.2017 09:52

psiklop, у нас в задачке есть специальный перечень "нестандартных"
- Фамилий
- Имен
- Отчеств
которые заполняют сами пользователи, если некая комбинация ФИО не обрабатывается нашей программой. ;)

psiklop 07.02.2017 15:25

У кого у вас? В какой задачке?
Я написал функцию на javascript на несколько коротких строк, она работает нормально как выяснилось в 99 из 100 и меня это полностью устраивает, может и еще кого устроит
Мне тут предлагают сервис, где надо регаться, получать api ключ, и еще держать в нем положительный баланс, я думаю это не в тему

а массив я еще улучшил кстати
var f = ["ов","ова","ев","ева","ко","ский","ская","чный","чная","ин","ина"];


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

ksa 08.02.2017 08:59

Цитата:

Сообщение от psiklop
У кого у вас? В какой задачке?

Знание этого не принципиально. :)
Мое сообщение призвано донести до тебя тот факт, что есть очень большое разнообразие "нестандартных" данных по ФИО... Причем у каждого региона свое. ;)
Вот и все.

psiklop 09.02.2017 14:53

Цитата:

Сообщение от ksa (Сообщение 443637)
Знание этого не принципиально. :)
Мое сообщение призвано донести до тебя тот факт, что есть очень большое разнообразие "нестандартных" данных по ФИО...

Ну так бы и написал сразу, а то у нас, у нас в задачке, то, се...
Хотя этот факт всем хорошо известен.

ksa 09.02.2017 14:57

Цитата:

Сообщение от psiklop
Ну так бы и написал сразу

Я так сразу и написал. :D
Де без БД с нестандартом тебе не обойтись...

psiklop 09.02.2017 15:07

А оно нужно так серьезно? Простая функция для формы, функция расставит заглавные буквы уже хорошо (и это самое важное), к примеру в неправильном порядке пишут 1%, нестандартных фамилий 10%, функция снизит значит неправильность до 0.1%

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

psiklop 09.02.2017 15:25

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

psiklop 09.02.2017 16:02

Я делал автозаполнение адреса через api вконтакте, и нельзя надеяться на 100%, там совсем не все улицы, попробовал сейчас dadata и тоже самое, отсутствуют те что и вконтакте, а вы еще и дома пытаетесь подставлять, еще скажу что многие тупят с этим автозаполнением, даже когда страна, город и улица в разных полях, а когда все в одном поле это реально сложно и лучше так не делать, покупатель запарится и уйдет.

рони 09.02.2017 18:55

Нормализация ФИО
 
psiklop,
вариант ...
function fiofix(str) {
    var f = /(ин|ина|ын|ына|ов|ова|ев|ева|ской|ская|цкой|их|ых|енко|ко|ук|юк|ский|ская|чный|чная)$/;
    var o = /(ич|вна|чна)$/;
    var i = /^(Марина|Ирина)$/;
    return str.trim().split(/\s+/)
        .map(function(s) {
            return s.toLowerCase().replace(/(^|\-)(\S)/g, function g(a, b, c) {
                return b + c.toUpperCase()
            });

        }).sort(function(a, b) {
            a = i.test(a) ? 1 : f.test(a) ? 0 : o.test(a) ? 2 : 1;
            b = i.test(b) ? 1 : f.test(b) ? 0 : o.test(b) ? 2 : 1;
            return a - b
        }).join(" ")
};

alert(fiofix(" сергеевна ИРИНА карпова  "));
alert(fiofix(" сергеевна ИРИНА карпова-карпенко  "));

psiklop 09.02.2017 23:11

Так конечно вообще коротко получилось
Не знаю конечно насчет 3 массива, все равно женских имен слишком много
Еще моя исправляла двойные фамилии типа карпова-карпенко

рони 09.02.2017 23:25

Цитата:

Сообщение от psiklop
Еще моя исправляла двойные фамилии типа карпова-карпенко

добавил, смотрите код выше

psiklop 03.04.2017 22:08

еще похожая функция для email, но я ее использую только как рекомендацию пользователю, дабы не было ошибок

function fixemail(email) {
var spisokmail = ["mail.ru","yandex.ru","gmail.com","rambler.ru","yahoo.com","qip.ru","outlook.com","hotmail.com","list.ru","inbox.ru","bk.ru","ya.ru","fastmail.com","icloud.com"];
var max = 0;
var fixemail, c, temp;
var domen = email.substr(email.indexOf("@")+1).toLowerCase();
if (spisokmail.indexOf(domen) == -1) {
for (var i = 0; i < spisokmail.length; i++) {
c = 0;
temp = spisokmail[i];
for (var i2 = 0; i2 < domen.length; i2++) {if (domen[i2] == ".") continue; if (temp.indexOf(domen[i2]) != -1) c++;}
if (((spisokmail[i].length-4)<c)&&(Math.abs(domen.length - spisokmail[i].length) < 2)) {
if ((c > max) || ((fixemail) && (c == max) && (fixemail.length > temp.length))) {fixemail = spisokmail[i]; max = c;}}}
if (fixemail) {return email.substr(0, email.indexOf("@")+1)+fixemail;}}
return email;}

alert(fixemail("ivan@mail.ru"));
alert(fixemail("ivan@mail.com"));
alert(fixemail("ivan@jmail.com"));
alert(fixemail("ivan@icloud.kom"));
alert(fixemail("ivan@yndeks.ru"));


Часовой пояс GMT +3, время: 09:31.