Source code for fuzzyfinder.main

# -*- coding: utf-8 -*-
import re
from . import export

[docs]@export def fuzzyfinder(input, collection, accessor=lambda x: x): """ Args: input (str): A partial string which is typically entered by a user. collection (iterable): A collection of strings which will be filtered based on the `input`. accessor (function): If the `collection` is not an iterable of strings, then use the accessor to fetch the string that will be used for fuzzy matching. Returns: suggestions (generator): A generator object that produces a list of suggestions narrowed down from `collection` using the `input`. """ suggestions = [] input = str(input) if not isinstance(input, str) else input pat = '.*?'.join(map(re.escape, input)) pat = '(?=({0}))'.format(pat) # lookahead regex to manage overlapping matches regex = re.compile(pat, re.IGNORECASE) for item in collection: r = list(regex.finditer(accessor(item))) if r: best = min(r, key=lambda x: len(x.group(1))) # find shortest match suggestions.append((len(best.group(1)), best.start(), accessor(item), item)) return (z[-1] for z in sorted(suggestions))