Как найти частичное совпадение строк?

у меня есть список строк, вот пример одной
0 .. трубок использовали для прожигания стальковша.Замена воронки 18м 8сл. Разлита полностью.

и надо определить содержится ли " трубок использовали для прожигания" в этой строке
НО:
могут быть ошибки/опечатки
Как это сделать?
  • Вопрос задан
  • 8906 просмотров
Решения вопроса 2
ri_gilfanov
@ri_gilfanov
Web- and desktop-developer
Без дополнительных библиотек и с использованием расстояния Дамерау-Левенштейна можно примерно так:
import re


def get_substrings(string):
    """Функция разбивки на слова"""
    return re.split('\W+', string)


def get_distance(s1, s2):
    """Расстояние Дамерау-Левенштейна"""
    d, len_s1, len_s2 = {}, len(s1), len(s2)
    for i in range(-1, len_s1 + 1):
        d[(i, -1)] = i + 1
    for j in range(-1, len_s2 + 1):
        d[(-1, j)] = j + 1
    for i in range(len_s1):
        for j in range(len_s2):
            if s1[i] == s2[j]:
                cost = 0
            else:
                cost = 1
            d[(i, j)] = min(
                d[(i - 1, j)] + 1,
                d[(i, j - 1)] + 1,
                d[(i - 1, j - 1)] + cost)
            if i and j and s1[i] == s2[j - 1] and s1[i - 1] == s2[j]:
                d[(i, j)] = min(d[(i, j)], d[i - 2, j - 2] + cost)
    return(d[len_s1 - 1, len_s2 - 1])


def check_substring(search_request, original_text, max_distance):
    """Проверка нечёткого вхождения одного набора слов в другой"""
    substring_list_1 = get_substrings(search_request)
    substring_list_2 = get_substrings(original_text)

    not_found_count = len(substring_list_1)

    for substring_1 in substring_list_1:
        for substring_2 in substring_list_2:
            if get_distance(substring_1, substring_2) <= max_distance:
                not_found_count -= 1

    if not not_found_count:
        return True


search_request = 'трубок использовали для прожигания'
original_text = 'трубок использовали для прожигания стальковша.Замена воронки 18м 8сл. Разлита полностью'

result = check_substring(search_request, original_text, max_distance=2)

print(result)  # True если найдено, иначе None


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

Чтобы ускорить нахождение расстояния ДЛ, можно использовать реализацию для Python на языке Си: https://github.com/gfairchild/pyxDamerauLevenshtein

Так же существуют менее точные, но более быстрые алгоритмы сравнения двух строк:
https://habr.com/ru/post/114997/
В PyPI и на GitHub должны быть библиотеки с готовыми реализациями наиболее востребованных из них.
Ответ написан
@deliro
pip3 install fuzzywuzzy[speedup]

from fuzzywuzzy import fuzz

x = "0 .. трубок использовали для прожигания стальковша.Замена воронки 18м 8сл. Разлита полностью."
y = "трубок использооали для прожигания"

fuzz.partial_ratio(x, y)


https://github.com/seatgeek/fuzzywuzzy
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы