import re

def fuzzy_filter(patterns, names):
    def match(pattern, words_index=0, pattern_index=0, word_index=0):
        return pattern_index == len(pattern) or (
            words_index < len(words) and word_index < len(words[words_index])
        ) and (
            pattern[pattern_index] == words[words_index][word_index] and (
                match(pattern, words_index, pattern_index + 1, word_index + 1) or
                match(pattern, words_index + 1, pattern_index + 1)
            ) or match(pattern, words_index + 1)
        )

    for name in names:
        words = list(map(str.lower, re.split(r'[\W_]+|(?<=\w)(?=[A-Z])', name)))
        if all(map(match, patterns.split())):
            yield name

file_names = [
    'HelloWorld.csv',
    'hello_windsor.pdf',
    'some_file_i_need.jpg',
    'san_francisco.png',
    'Another.file.txt',
    'A file name.rar'
]

queries = '''\
hw
hwor
winds
sf
file need
sfr
file
file another
fnrar'''.splitlines()

for query in queries:
    print(f'{query} -> {", ".join(fuzzy_filter(query, file_names))}')