首页 > 解决方案 > If i in string but partial is even ok python

问题描述

I am sure this is simple but I can't see or possibly can't find a solution.

Suppose I have a string, for example something--abcd--something and I want to find abcc in the string. I want to allow for one mismatch, meaning that the output of the below code should be True.

my_string='something--abcd--something'
substring = 'abcc'

if substring in my_string:
    print('True')
else:
    print('False')

I know that the substring is not in my_string but then what I want is to allow for one mismatch then the output will be True.

How can I achieve that?

标签: pythonstringif-statementstring-matching

解决方案


There are certainly finer ways to do it, but one solution is to search for it with regexes in which one of the characters is replaced by a dot (or '\w' if you want the character to be a letter and nothing else).

We use a generator to lazily generate the regexes by replacing one of the letters each time, then check if any of these regexes match:

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

The with_one_dot(s) generator yields s with one letter replaced by a dot on each iteration:

for reg in with_one_dot('abcd'):
    print(reg)

outputs:

.bcd
a.cd
ab.d
abc.

Each of these strings is used as a regex and tested on my_string. The dot . in a regex means 'match anything', so it allows any symbol instead of the original letter.

any returns True immediately if any of theses regexes matches, False if none does.


推荐阅读