Search code examples
pythonpattern-matchingwildcard

Looping through list for a pattern match with strings with wildcards


I have sample code of a function in which uses pattern matching to match a string value containing wildcards with an actual string value.

def isMatch(text, pattern):
    n = len(text)
    m = len(pattern)
    i = 0
    j = 0
    startIndex = -1
    match = 0

    while i < n:
        if j < m and (pattern[j] == '?' or pattern[j] == text[i]):
            i += 1
            j += 1
        elif j < m and pattern[j] == '*':
            startIndex = j
            match = i
            j += 1
        elif startIndex != -1:
            j = startIndex + 1
            match += 1
            i = match
        else:
            return False

    while j < m and pattern[j] == '*':
        j += 1

    return j == m


s = "RE340T6-1MCWW"
p = "RE340T*-*****"

if isMatch(s, p):
    print("Yes")
else:
    print("No")

In this sample code, the string (s) "RE340T6-1MCWW" matches the pattern (p), "RE340T*-*****" and returns a "Yes", as it should.

What I want to do is using the above function,have a list of strings and find the matches in a list of strings with wildcards. For example:

s = ['GUC 40 410','HUC 40 410','XUC 40 410']
p = ['GUC 40 4**','HUC 40 4**','XUC 40 4**']

I don't know how to insert looping through the lists in the function to return where the string (s) matches the pattern (p). Any ideas for the next step?

If I just substitute the list for the static string, it just returns a "No"


Solution

  • You can simply use another _find method to check for isMatch():

    def isMatch(text, pattern):
        n, m = len(text), len(pattern)
        i, j = 0, 0
        startIndex = -1
        match = 0
    
        while i < n:
            if j < m and (pattern[j] == '?' or pattern[j] == text[i]):
                i += 1
                j += 1
            elif j < m and pattern[j] == '*':
                startIndex = j
                match = i
                j += 1
            elif startIndex != -1:
                j = startIndex + 1
                match += 1
                i = match
            else:
                return False
    
        while j < m and pattern[j] == '*':
            j += 1
    
        return j == m
    
    
    def _find(S, ps):
        res = []
        for i, s in enumerate(S):
            for j, p in enumerate(ps):
                if isMatch(s, p):
                    res.append((i, j))
        return res
    
    
    s = ['GUC 40 410', 'HUC 40 410', 'XUC 40 410']
    p = ['GUC 40 4**', 'HUC 40 4**', 'XUC 40 4**']
    
    print(_find(s, p))
    
    

    Prints

    [(0, 0), (1, 1), (2, 2)]