Заставляя difflib SequenceMatcher игнорировать "мусорные" символы

У меня есть много строк, которые я хочу сопоставить по сходству (каждая строка в среднем 30 символов). я нашел difflib'sSequenceMatcher отлично подходит для этой задачи, так как это было просто и нашло хорошие результаты. Но если я сравню hellboy а также hell-boy как это

>>> sm=SequenceMatcher(lambda x:x=='-','hellboy','hell-boy')
>>> sm.ratio()
0: 0.93333333333333335

Я хочу, чтобы такие слова соответствовали 100%, т.е. ratio of 1.0, Я понимаю, что символ барахла, указанный в функции выше, не используется для сравнения, но находит самую длинную непрерывную совпадающую подпоследовательность. Есть ли способ, которым я могу сделать SequenceMatcherигнорировать некоторые "ненужные" символы для сравнения?

2 ответа

Решение

Если вы хотите сделать, как я предложил в комментариях, (удаление ненужных символов) самый быстрый способ - это использовать str.translate(),

Например:

to_compare = to_compare.translate(None, {"-"})

Как показано здесь, это значительно (в 3 раза) быстрее (и мне приятнее читать), чем регулярное выражение.

Обратите внимание, что в Python 3.x, или если вы используете Unicode в Python 2.x, это не будет работать как delchars параметр не принят. В этом случае вам просто нужно сопоставить None. Например:

translation_map = str.maketrans({"-": None})
to_compare = to_compare.translate(translation_map)

У вас также может быть небольшая функция для сохранения набора текста, если у вас есть много символов, которые вы хотите удалить, просто сделайте набор и пропустите:

def to_translation_map(iterable):
    return {key: None for key in iterable}
    #return dict((key, None) for key in iterable) #For old versions of Python without dict comps.

Если бы вам нужно было сделать функцию для удаления всего ненужного символа перед рукой, вы могли бы использовать re:

string=re.sub('-|_|\*','',string)

для регулярного выражения '-|_|\*' просто положить | между всеми ненужными символами, и если его специальный повторный символ положить \ до этого (как * а также +)

Другие вопросы по тегам