python基本的正则表达式函数

时间:2018-01-31 04:10:44

标签: python regex

我正在尝试编写一个实现简单正则表达式匹配算法的函数。特殊字符“*”和“?”应分别代表1和n> = 0自由度。例如字符串

y="abc" and x="a*c",
y="abc" and x="a?c",
y="abddddzfjc" and x="a?" or x="a?c"

应该返回True,而字符串

y="abcd" and x="a*d",
y="abcdef" and x="a?d*"

应该返回False。

我的方法是在循环中运行并缩短字符串,因为每个后续匹配都被识别,这对于相同的匹配或单个*与字母字符匹配工作正常,但我对如何为边缘情况执行此操作感到困惑像最后一个例子。处理“?”的情况有n个自由度,我在右边的字符串中向前循环以找到下一个字母字符,然后尝试在左边的字符串中查找该字符,从右到左查看。我相信有一种更优雅的方式(也许有发电机?!)。

def match_func(x,y):
  x, y = list(x), list(y)
  if len(x)==len(y)==1:
    if x[0] == y[0] or bool((set(x)|set(y)) & {"?","*"})
    return True
  elif len(x)>0 and len(y)==0:
    return False
  else:
    for ix, char in enumerate(x):
      if char==y[ix] or char=="*":
        return match_func(x[ix+1:],y[ix+1:])
      else:
        if char=="?"
          if ix==len(x)=1: return True
          ##check if the next letter in x has an eventual match in y
          peek = ix+1
          next_char = x[peek]

          while peek<len(x)-1:
            next_char = x[peek]
            if next_char.isalpha():
              break
            else: peek+=1

          if peek == len(x)-1:
            return True

          ys = ''.join(y)

          next_char_ix = ys[ix].rfind(next_char)
          ##search y for next possible match?

          if next_char_ix!=-1:
            return match_func(x[peek:], y[next_char_ix:])
          else:
            return False

        else:
          return False
    return True

1 个答案:

答案 0 :(得分:0)

首先决定是否将匹配算法设为 minimal maximal 搜索。这意味着,如果您的模式是a,并且您的主题字符串是aa,那么匹配是在第一个还是第二个位置发生的?当你陈述问题时,任何一种选择似乎都是可以接受的。

做出这个选择之后,你将会清楚地知道如何遍历字符串 - 尽可能向右移动然后向后工作直到你匹配或失败;或者从左边开始,每次尝试后回溯。

我建议使用递归实现。在每个位置,评估您是否有匹配。如果是这样,请使您的递归调用在模式和主题字符串中向前推进适当的数量。如果没有,请放弃。如果模式的第一个字符不匹配,则仅前进主题字符串(根据您的最小/最大选择),然后重试。

棘手的部分是,你必须考虑模式中的可变长度标记作为可能的匹配,即使相同的字符也匹配该通配符后面的文字字符。这使你进入深度优先搜索的领域。评估像a?a?a?a这样的主题字符串上的aaaabaaaa等模式会很有趣,如果你把它推得太远,可能需要数年才能完成。

你的教授很好地选择了正则表达式运算符,让你做出有意义的深度分配,而没有编写一个完整的解析器和词法分析器,以使事情有效。

祝你好运!