Python循环字符串并与通配符模式匹配
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']
,也就是说,这个模式可以找到两次,使用这些替换。