Python循环字符串并与通配符模式匹配

1 投票
1 回答
2597 浏览
提问于 2025-04-18 12:47
string1="abc"
string2="abdabcdfg"

我想检查字符串 string1 是否是字符串 string2 的子串。不过,里面有一些通配符,比如 "." 可以代表任何字母,y 可以是 "a""d"x 可以是 "b""c"。所以,像 ".yx" 这样的字符串会是 string2 的子串。

我该怎么用一个循环来实现这个呢?我想遍历 string2,并在每个位置进行比较。我试过用字典,但我想用循环来做。我的代码是:

def wildcard(string,substring):
    sum=""
    table={'A': '.', 'C': '.', 'G': '.', 'T': '.','A': 'x', 'T': 'x', 'C': 'y', 'G': 'y'}
    for c in strand:
        if (c in table) and table[c] not in sum:
            sum+=table[c]
        elif c not in table:
            sum+=c
    if sum==substring:
        return True
    else:
        return False

print wildcard("TTAGTTA","xyT.")#should be true

1 个回答

1

我知道你特别想要一个用循环的解决方案。不过,我想提供一个不同的思路:你可以把你的模式转换成一个正则表达式。这是一种用于处理字符串模式的语言,功能要强大得多。然后你可以使用re模块来检查这个正则表达式(也就是你的子字符串模式)是否可以在字符串中找到。

def to_regex(pattern, table):
    # join substitutions from table, using c itself as default
    return ''.join(table.get(c, c) for c in pattern)

import re
symbols = {'.': '[a-z]', '#': '[ad]', '+': '[bc]'}
print re.findall(to_regex('.+#', symbols), 'abdabcdfg')

如果你更喜欢一种“动手”的解决方案,你可以使用这个,利用循环来实现。

def find_matches(pattern, table, string):
    for i in range(len(string) - len(pattern) + 1):
        # for each possible starting position, check the pattern
        for j, c in enumerate(pattern):
            if string[i+j] not in table.get(c, c):
                break # character does not match
        else:
            # loop completed without triggering the break
            yield string[i : i + len(pattern)]

symbols = {'.': 'abcdefghijklmnopqrstuvwxyz', '#': 'ad', '+': 'bc'}
print list(find_matches('.+#', symbols, 'abdabcdfg'))

无论哪种方法,输出结果都是['abd', 'bcd'],也就是说,这个模式可以找到两次,使用这些替换。

撰写回答