在python中搜索字符串中的模式

时间:2014-02-25 21:29:09

标签: python string pattern-matching match

问题:我对python很新,所以请耐心等待。这是一项家庭作业,我需要一些帮助。

因此,对于matchPat函数,我需要编写一个函数,该函数将接受两个参数str1和str2,并返回一个布尔值,指示str1是否在str2中。但是我必须在str1中使用星号作为通配符。 *只能在str1中使用,它将代表我需要忽略的一个或多个字符。 matchPat的示例如下:

matchPat('a * t * r','anteaters'):是的

matchPat('a * t * r','albatross'):是的

matchPat('a * t * r','artist'):False

我当前的matchPat函数可以判断str1的字符是否在str2中,但我真的不知道如何告诉python(使用*作为外卡)来查找'a'(第一个字母)在找到a之后,跳过下一个0个或更多个字符,直到找到下一个字母(在示例中为't'),依此类推。

def matchPat(str1,str2):
    ## str(*)==str(=>1)
    if str1=='':
        return True
    elif str2=='':
        return False
    elif str1[0]==str2[0]:
        return matchPat(str1[2],str2[len(str1)-1])
    else: return True

5 个答案:

答案 0 :(得分:2)

Python字符串有in运算符;您可以使用str1检查str2str1 in str2的子字符串。

您可以根据令牌将split字符串放入子字符串列表中。 "a*b*c".split("*")["a","b","c"]

您可以使用字符串的find方法找到字符串中下一个子字符串出现的偏移量。

因此,通配符匹配的问题变为:

  1. 将图案分割成由astrix分隔的部分
  2. 对于模式的每个部分
  3. 我们可以在上一部分的位置后找到这个吗?
  4. 您将不得不应对角落案例,例如以星号开头或结尾的图案,或者彼此旁边有两个星号,依此类推。祝好运!

答案 1 :(得分:1)

有一个find()字符串方法,用于搜索特定点的子字符串,返回其索引(如果找到)或返回-1(如果未找到)。 index()方法类似,但如果找不到目标字符串则会引发异常。

我建议您先将模式字符串拆分为“*”。这将为您提供要查找的块列表。将起始位置设置为零,对于块列表中的每个元素,从当前位置执行find()index()

如果找到当前的块,则从其起始位置和长度开始计算,开始搜索下一个块并更新起始位置。如果找到所有块,则目标字符串与模式匹配。如果缺少任何块,则模式搜索将失败。

由于这是作业,我希望能让你有足够的想法继续前进。

答案 2 :(得分:0)

在没有给出完整答案的情况下,首先,将str1字符串拆分为'*'字符的字符串列表。我通常将str1称为“针”,将str2称为“草堆”,因为你正在寻找大海捞针。

needles = needle.split('*')

接下来,让一个计数器(我将称之为i)从0开始。你将一直在看干草堆[i:]寻找针的下一个字符串。

在伪代码中,它看起来像这样:

needles = needle.split('*')
i = 0
loop through all strings in needles:
    if current needle not in haystack[i:], return false
    increment i to just after the occurence of the current needle in haystack (use the find() string method or write your own function to handle this)
return true

答案 3 :(得分:0)

这里的基本思路是比较str1和str2中的每个字符,如果str1中的char是“*”,则在str2中找到str1中的字符,即str1中“*”旁边的字符。

假设你不打算使用任何函数,(除了find(),这可以很容易地实现),这是一个很难的方法(代码很简单,但很麻烦,我尽可能评论) -

def matchPat(str1, str2):
    index1 = 0
    index2 = 0
    while index1 < len(str1):
        c = str1[index1]
        #Check if the str2 has run it's course.
        if index2 >= len(str2):
            #This needs to be checked,assuming matchPatch("*", "") to be true
            if(len(str2) == 0 and str1 == "*"):
                return True
            return False
        #If c is not "*", then it's normal comparision.
        if c != "*":
            if c != str2[index2]:
                 return False
            index2 += 1
        #If c is "*", then you need to increment str1,
        #search for the next value in str2,
        #and update index2
        else:
            index1 += 1
            if(index1 == len(str1)):
                return True       
            c = str1[index1]
            #Search the character in str2
            i = str2.find(c, index2)
            #If search fails, return False
            if(i == -1):
                return False
            index2 = i + 1
        index1 += 1
    return True

输出 -

print matchPat("abcde", "abcd")
#False
print matchPat("a", "")
#False
print matchPat("", "a")
#True
print matchPat("", "")
#True
print matchPat("abc", "abc")
#True
print matchPat("ab*cd", "abacacd")
#False
print matchPat("ab*cd", "abaascd")
#True
print matchPat ('a*t*r', 'anteater')
#True
print matchPat ('a*t*r', 'albatross')
#True
print matchPat ('a*t*r', 'artist')
#False

答案 4 :(得分:-1)

您是否可以使用正则表达式?如果是这样,您正在寻找的功能已经存在于re.search功能中:

import re
bool(re.search('a.t.r', 'anteasters')) # True
bool(re.search('a.t.r', 'artist' ))    # False

如果星号是严格必要的,你也可以使用正则表达式:

newstr = re.sub('\*', '.', 'a*t*r')    # Replace * with .
bool(re.search(newstr, 'anteasters'))  # Search using the new string

如果不允许使用正则表达式,最简单的方法是查看与第一个字符串长度相同的第二个字符串的子字符串,并比较这两个字符串。像这样:

def matchpat(str1, str2):
    if len(str1) > len(str2): return False  #Can't match if the first string is longer
    for i in range(0, len(str2)-len(str1)+1):
        substring = str2[i:i+len(str1)] # create substring of same length as first string
        for j in range(0, len(str1)):
            matched = False                        # assume False until match is found
            if str1[j] != '*' and str1[j] != substring[j]: # check each character
                break
            matched = True
        if matched == True: break # we don't need to keep searching if we've found a match
    return matched