Сравнивая строки в python, чтобы найти ошибки - PullRequest
2 голосов
/ 27 сентября 2011

У меня есть строка, которая является правильным написанием слова:

FOO

Я бы позволил кому-нибудь неправильно набрать слово таким образом:

FO, F00, F0O ,FO0

Есть хороший способ проверить это? Нижний регистр также следует рассматривать как правильный или преобразовывать в верхний регистр. Что когда-либо было бы самым красивым.

Ответы [ 3 ]

6 голосов
/ 27 сентября 2011

Одним из подходов является вычисление расстояния редактирования между строками. Например, вы можете использовать расстояние Левенштейна или изобрести собственную функцию расстояния, которая рассматривает 0 и O ближе, чем 0 и P, например.

Другой способ - преобразовать каждое слово в каноническую форму и сравнить канонические формы. Например, вы можете преобразовать строку в верхний регистр, заменить все 0 на Os, 1 на Is и т. Д., А затем удалить дублирующиеся буквы.

>>> import itertools
>>> def canonical_form(s):
        s = s.upper()
        s = s.replace('0', 'O')
        s = s.replace('1', 'I')
        s = ''.join(k for k, g in itertools.groupby(s))
        return s
>>> canonical_form('FO')
'FO'
>>> canonical_form('F00')
'FO'
>>> canonical_form('F0O')
'FO'
2 голосов
/ 27 сентября 2011

Встроенный модуль difflib имеет функцию get_close_matches .

Вы можете использовать его следующим образом:

>>> import difflib
>>> difflib.get_close_matches('FO', ['FOO', 'BAR', 'BAZ'])
['FOO']
>>> difflib.get_close_matches('F00', ['FOO', 'BAR', 'BAZ'])
[]
>>> difflib.get_close_matches('F0O', ['FOO', 'BAR', 'BAZ'])
['FOO']
>>> difflib.get_close_matches('FO0', ['FOO', 'BAR', 'BAZ'])
['FOO']

Обратите внимание, что он не соответствует ни одному из вашихслучаев.Вы можете уменьшить параметр cutoff, чтобы получить соответствие:

>>> difflib.get_close_matches('F00', ['FOO', 'BAR', 'BAZ'], cutoff=0.3)
['FOO']
1 голос
/ 28 сентября 2011

вы можете использовать модуль 're'

re.compile(r'f(o|0)+',re.I) #ignore case

вы можете использовать фигурные скобки, чтобы ограничить количество вхождений тоже.Вы также можете получить «причудливые» и определить свои наборы «leet» и добавить их в w /% s

как в:

ay = '(a|4|$)'
oh = '(o,0,\))'
re.compile(r'f%s+' % (oh),re.I)
...