Python regex fuzzy searching

Viewed 89

I have a question about making a pattern using fuzzy regex with the python regex module.

I have several strings such as TCATGCACGTGGGGCTGAC

The first eight characters of this string are variable (multiple options): TCAGTGTG, TCATGCAC, TGGTGGCT. In addition, there is a constant part after the variable part: GTGGGGCTGAC.

I would like to design a regex that can detect this string in a longer string, while allowing for at most 2 substitutions.

For example, this would be acceptable as two characters have been substituted:

TCATGCACGTGGGGCTGAC
TCCTGCACGTGGAGCTGAC

However, more substitutions should not be accepted.

In my code, I tried to do the following:

import regex

variable_parts = ["TCAGTGTG", "TCATGCAC", "TGGTGGCT", "GATAAGTG", "ATTAGACG", "CACTTCCG", "GTCTGTAT", "TGTCAAAG"]
string_to_test = "TCATGCACGTGGGGCTGAC"
motif = "(%s)GTGGGGCTGAC" % "|".join(variable_parts)
pattern = regex.compile(r''+motif+'{s<=2}')

print(pattern.search(string_to_test))

I get a match when I run this code and when I change the last character of string_to_test. But when I manually add a substitution in the middle of string_to_test, I do not get any match (even while I want to allow up to 2 substitutions).

Now I know that my regex is probably total crap, but I would like to know what I exactly need to do to make this work and where in the code I need to add/remove/change stuff. Any suggestions/tips are welcome!

1 Answers

Right now, you only add the restriction to the last C in the pattern that looks likelooks like (TCAGTGTG|TCATGCAC|TGGTGGCT|GATAAGTG|ATTAGACG|CACTTCCG|GTCTGTAT|TGTCAAAG)GTGGGGCTGAC{s<=2}.

To apply the {s<=2} quantifier to the whole expression you need to enclose the pattern within a non-capturing group:

pattern = regex.compile(fr'(?:{motif}){{s<=2}}')

The example above shows how to declare your pattern with the help of an f-string literal, where literal braces are defined with {{ and }} (doubled) braces. It yields the same result as pattern = regex.compile('(?:'+motif+'){s<=2}').

Also, note that r''+ is redundant and has no effect on the final pattern.

Related