Мне пришёл в голову следующий примитивный алгоритм:
- предобработка: переводим в строке заглавные символы в строчные ("Гайка" -> "гайка")
- разбиваем строку на токены/слова, разделяемые любым количеством пробелов ("ббб ааа ввв" -> ["ббб", "ааа", "ввв"])
- полученный массив слов сортируем лексикографически (["ааа", "ббб", "ввв"])
- для последующего сравнения соединим обратно в строку (["ааа", "ббб", "ввв"] -> "ааа ббб ввв")
- полученные "нормализованные" строки сравниваем при помощи расстояния Левенштейна
Согласно этому алгоритму из строк "Автоматический выключатель KDJF39484" и "Выключатель автоматический KDJF39484" на выходе получится одинаковая строка "kdjf39484 автоматический выключатель".
Таким образом, расстояние Левенштейна между ними будет равно нулю.
Для строк "гайка СБВ-4В ГОСТ.83", "Гайка СБВ-4ВГОСТ.83" результат хуже ожидаемого из-за того что отсортированы слова "СБВ-4В ГОСТ.83" как "гост.83 сбв-4в". Так получилось из-за того что слитно были написаны каталоговый номер и название стандарта.
Для решения данной проблемы я бы получил из БД репрезентативную выборку всех возможных вариантов наименований, в которых фигурирует "ГОСТ" (без разницы заглавными или строчными) и тогда составил бы правила для отделения от других слов через пробел при помощи регулярных выражений или другими способами. Аналогично в случае с другими названиями стандартов (ISO, ...).
Пример на языке Ruby:
https://gist.github.com/romiras/386e3694a59949f6be...simple_fuzzy_match(
' Автоматический выключатель KDJF39484 ',
'Выключатель автоматический KDJF39484'
)
выдаёт разницу 0 для "нормализованных" строк, следовательно, они идентичны.