Я уверен, что это просто, но я не вижу или, возможно, не могу найти решение.
Предположим, у меня есть строка, например something--abcd--something
, и я хочу найти abcc
в строке. Я хочу допустить одно несоответствие, а это означает, что вывод приведенного ниже кода должен быть True
.
my_string='something--abcd--something'
substring = 'abcc'
if substring in my_string:
print('True')
else:
print('False')
Я знаю, что substring
не находится в my_string
, но тогда я хочу допустить одно несоответствие, тогда вывод будет True.
Как я могу этого добиться?
Если вам нужно «нечеткое» соответствие, вы не можете использовать in
.
Если строка, которую вы ищете, короткая и не может содержать символы, которые используются в регулярных выражениях (например, / . * и т. д.), вы можете попробовать re.match(".bcd", my_string)
a.cd
ab.d
и abc.
, но гораздо лучше использовать библиотеку нечеткого сопоставления строк. способ пойти.
@Samwise и @John Gordon - К сожалению, я не могу использовать "fuzzy" для того, что хочу исполнить. В файле у меня есть несколько строк разной длины (подстрока всегда одинаковой длины), поэтому установка fuzz.ratio
для меня не работает.
Конечно, есть более тонкие способы сделать это, но одно из решений — искать его с помощью регулярных выражений, в которых один из символов заменяется точкой (или '\w', если вы хотите, чтобы символ был буквой и ничем другим).
Мы используем генератор для ленивой генерации регулярных выражений, каждый раз заменяя одну из букв, а затем проверяем, совпадают ли какие-либо из этих регулярных выражений:
import re
def with_one_dot(s):
for i in range(len(s)):
yield s[:i] + '.' + s[i+1:]
def match_all_but_one(string, target):
return any(re.search(fuzzy_target, string) for fuzzy_target in with_one_dot(target))
def find_fuzzy(string, target):
" Return the start index of the fuzzy match, -1 if not found"
for fuzzy_target in with_one_dot(target):
m = re.search(fuzzy_target, string)
if m:
return m.start()
return -1
my_string = 'something--abcd--something'
print(match_all_but_one(my_string, 'abcc')) # 1 difference
# True
print(find_fuzzy(my_string, 'abcc'))
# 11
print(match_all_but_one(my_string,'abbb')) # 2 differences
# False
print(find_fuzzy(my_string, 'abbb'))
# -1
Генератор with_one_dot(s)
выдает s
с заменой одной буквы точкой на каждой итерации:
for reg in with_one_dot('abcd'):
print(reg)
выходы:
.bcd
a.cd
ab.d
abc.
Каждая из этих строк используется как регулярное выражение и тестируется на my_string
. Точка .
в регулярном выражении означает «сопоставить что угодно», поэтому вместо исходной буквы допускается любой символ.
any
немедленно возвращает True
, если какое-либо из этих регулярных выражений совпадает, False, если ни одно из них не соответствует.
Уважаемый @Thierry, спасибо за подробный ответ. Чтобы освежить мой мозг, не могли бы вы дать немного больше деталей о последних строках двух определений? Я собираюсь реализовать ваш код, ища две подстроки для строки.
Уважаемый @Thierry, не могли бы вы упомянуть, как я могу найти положение «abcc», когда match_all_but_one
равно True
? Поскольку его нет в основной строке, использовать параметр find
в python сложно.
Я отредактировал ответ. Для ваших будущих вопросов, пожалуйста, убедитесь, что все ваши требования четко указаны в вопросе, когда вы публикуете его, так как некоторые из них могут повлиять на способ построения решения!
Это недоступно как встроенная функция в Python, но проверьте datacamp.com/community/tutorials/fuzzy-string-python