字符串正则表达式两个不匹配的Python

时间:2015-07-12 06:47:55

标签: python regex string-matching

如何扩展下面的代码以允许我探索我的子字符串和父字符串之间有2个不匹配或更少的所有实例?

子字符串:SSQP

String-to-match-to:SSPQQQQPSSSSQQQSSQPSPSQSSQPSSQPPSSSSQPSPSQSSQPSSSSQPSPSQSSQPSSSSQPSPSQ

以下是仅包含一个可能不匹配的示例:

>>> s = 'SSPQQQQPSSSSQQQSSQPSPSQSSQPSSQPPSSSSQPSPSQSSQPSSSSQPSPSQSSQPSSSSQPSPSQ'
>>> re.findall(r'(?=(SSQP|[A-Z]SQP|S[A-Z]QP|SS[A-Z]P|SSQ[A-Z]))', s)
['SSQQ', 'SSQP', 'SSQP', 'SSQP', 'SSQP', 'SSQP', 'SSQP', 'SSQP', 'SSQP']

显然,在上面的代码中加入两个不匹配的可能性需要对所有可能的组合进行大量的暴力分类。

如何扩展此代码(或重构此代码)以探索两个不匹配的可能性?

此外,我想修改输出,以便获得子字符串与字符串匹配的确切位置的数字索引(不是SSQQSSQP)。

2 个答案:

答案 0 :(得分:5)

您不必在此使用class MovieSerializer(serializers.ModelSerializer): """ Serialiazing all the Movies. """ genre = MyPrimaryKeyRelatedField(many=True, queryset=Genre.objects.all()) directorName = MyPrimaryKeyRelatedField(queryset=Director.objects.all()) owner = serializers.ReadOnlyField(source='owner.username') class Meta: model = Movie fields = ('popularity',"directorName",'genre','imdbScore','name','owner') ,而是可以使用itertools模块,并节省大量内存。

您可以先提取长度为4的所有子字符串,然后将其与re进行比较,然后选择与您的substring差别较小的字符串:

substring

演示:

from itertools import izip,islice,tee

def sub_findre(s,substring,diffnumber):
    sublen=len(substring)
    zip_gen=(izip(substring,islice(s,i,i+sublen)) for i in xrange(len(s)))
    for z in zip_gen:
        l,z=tee(z)
        if sum(1 for i,j in l if i==j)>=sublen-diffnumber:
            new=izip(*z)
            next(new)
            yield ''.join(next(new))

如果您想要返回索引,您需要将索引放在s='SSPQQQQPSSSSQQQSSQPSPSQSSQPSSQPPSSSSQPSPSQSSQPSSSSQPSPSQSSQPSSSSQPSPSQ' substring='SSQP' print list(sub_findre(s,substring,2)) ['SSPQ', 'SPQQ', 'QQQP', 'SSSS', 'SSSQ', 'SSQQ', 'SQQQ', 'SSQP', 'PSQS', 'SSQP', 'SSQP', 'SQPP', 'SSSS', 'SSSQ', 'SSQP', 'PSQS', 'SSQP', 'SSSS', 'SSSQ', 'SSQP', 'PSQS', 'SSQP', 'SSSS', 'SSSQ', 'SSQP', 'PSQ'] 中,您可以使用izip重复索引,其长度为itertools.repeat()

substring

演示:

from itertools import izip,islice,tee,repeat

def sub_findre(s,substring,diffnumber):
    sublen=len(substring)
    zip_gen=(izip(substring,islice(s,i,i+sublen),repeat(i,sublen)) for i in xrange(len(s)))
    for z in zip_gen:
        l,z=tee(z)
        if sum(1 for i,j,_ in l if i==j)>=sublen-diffnumber:
            new=izip(*z)
            next(new)
            next(new)
            yield next(new)[0]

答案 1 :(得分:3)

组合爆炸对于四个中的两个不匹配不是

首先,请注意您可以省略<a href="#/projectpersons/{{projects.person.id}}" class="cardBody btn-link">View More</a> 本身,因为它被所有较宽松的案例所覆盖。

SSQP

因此,案件数量为

re.findall(r'(?=([A-Z]SQP|S[A-Z]QP|SS[A-Z]P|SSQ[A-Z]))', s)

对于最多两个不匹配,案例数

               4!
C(4, 1) = ––––––––––––– = 4
          1! * (4 - 1)!

即,

               4!
C(4, 2) = ––––––––––––– = 6
          2! * (4 - 2)!

(为了简化说明,我冒昧地写re.findall('(?=(SS..|S.Q.|S..P|.SQ.|.S.P|..QP))', s) 代替.。)

获取比赛的位置而不是比赛的文字:

[A-Z]