Заставляя difflib SequenceMatcher игнорировать "мусорные" символы
У меня есть много строк, которые я хочу сопоставить по сходству (каждая строка в среднем 30 символов). я нашел difflib's
SequenceMatcher
отлично подходит для этой задачи, так как это было просто и нашло хорошие результаты. Но если я сравню 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)
для регулярного выражения '-|_|\*'
просто положить | между всеми ненужными символами, и если его специальный повторный символ положить \
до этого (как *
а также +
)