00:00
我们已经了解了,个体模式其实就是针对简单事件的匹配规则,那接下来我们当然就应该要把简单事件按照特定的顺序连接起来,组合成一个完整的复杂事件,那这样的话,对应的个体模式也就应该按照一定的顺序连接起来,组成一个完整的匹配规则。诶,那这一套完整的匹配规则就叫做组合模式啊,那有时候我们会发现啊,组合模式是由个体模式组合起来的嘛,拼接起来的嘛,而且是拼接成了从前到后按照顺序的一个序列,所以有时候也把它叫做模式序列。那整体来看的话,一个模式序列简单来讲就是每一个个体模式用一些连接词,把它按照前后的顺序,以及它们之间的这种。
01:03
是紧挨着还是中间可以隔开一些其他的事件,这样的一个近邻关系组合起来的一个结果啊,那一般情况呢,组合模式是这样的一个形式,就是首先是调用pattern点方法,这是表示我们开始的这一个简单事件,第一个个体模式,然后之后呢,呃,可能就会接着ne或者followed等等等等不同的连接词,把不同的个体模式。组合在一起构成一个序列啊,那我们知道当前每一步方法调用,其实返回的都是一个pattern对象。所以当前。组合模式或者说模式序列返回的内容跟个体模式其实是一样的,都是pattern的对象。那接下来我们就分别来介绍一下组合模式当中的不同的连接词,或者说不同的具体模式。
02:02
那首先第一个就是所谓的初始模式,因为所有的组合模式,所有的这个模式序列都得有个头啊,那开头的时候是怎么样去调用呢?都是pattern begin方法,用这种方法创建一个初始模式,那这里面传入的string参数呢,就是当前第一个个体模式的名称。这里面需要注意就是begin方法呢,还需要传一个类型参数,这其实就是整个我们模式当中需要去检测的事件的基本类型啊,那。返回的值呢,当然就是一个pattern对象啊啊,那这里面我们可以看到pattern本身是有两个泛型的,前面对应的这个泛型当然就是当前检测事件的基本类型,这里边我们定义的是eventt,而后边这里呢,给了一个通配符问号,诶,那所以这里边是自动推断第二个泛型的,这里边的第二个泛型其实指的就是当前模式里边事件的子类型。
03:11
它主要就是由类型限制条件啊。来定义的啊,那所以这样的话,我们就得到了一个初始的模式,然后有了这个初始模式之后呢,那之后就可以按照复杂事件的顺序依次往后面追加个体模式,组成一个模式序列了啊,那接下来呢,我们要关键去考察的就是。组成模式序列的之间连接个体模式的这些连接词,它到底是哪些连接词?这些连接词呢?关键是要表明先后发生的事件之间是有怎样的近邻关系,哎,那所以这里边我们要看一下有什么样的近邻关系呢?Li和capp里边提供了这样的三种,首先就是严格竞邻。
04:06
啊,这里我们可以根据这个图来考察一下啊,所谓的严格精灵其实非常简单,就是。复杂事件中匹配的事件啊,严格的按照顺序一个接一个出现,紧挨着中间没有任何其他的事件,比如说这里我们左边的这个图,当前的模式,如果是严格近邻。先是一个圆圈,后边是一个三角的话,那么上面输入事件流里边对应的匹配就只有后边的这一组。复杂事件。前面即使前面有圆圈,后边有三角,但是因为中间隔了方框这样的事件,其他事件,所以对应的就不能匹配出来,这就好比之前我们所说的。连续三次登陆失败,中间显然是不能有其他的登陆成功的事件的啊,所以之前我们的定义其实就是要求一个严格禁邻关系,那所以严格竞邻关系呢,在代码当中调用的就是点next方法,之前我们在代码里边也确实是用点next来定义的,Next从英文上含义上来讲就是下一个嘛,下一个当然就是中间没有其他的时间。
05:23
那与之对应的呢?另外一种竞邻模式,就是所谓的宽松近邻模式。宽松竞邻模式所说的呢?就是只关心当前,前面一个圆圈,后面一个三角,只关心他们俩的前后顺序。至于他们中间有没有隔着其他的事件,这个没有关系啊,就是中间可以插入其他的事件。所以对于上面这个输入事件流,如果我们定义这样一个宽松镜模式的话,呃,除了前面后边的这个圆圈和三角紧挨着的这个可以检测匹配出来,而前面的这一个圆圈和三角中间隔了方框,也是可以检测匹配到。
06:08
代码当中呢,这一部分用的是点followed by方法,顾名思义followed by,那就是跟在后面,不需要紧密相连。除此之外呢,另外还有一种更加宽松的竞灵方式,叫做非确定性宽松竞礼,诶这个是什么意思呢?主要就是说我们可以使用之前已经匹配过的事件进行重复匹配,哎,那我们看一下这个具体的例子就可以看得出来啊,假如说当前还是针对前面一个圆圈,后面一个三角,我们做一个非确定性宽松径灵的话,诶,那就是不光可以匹配出前面宽松匹配出的这两种情况。另外呢?当前前面有一个圆圈。它可以跟后边的所有三角都做一个匹配,把它们作为一个复杂事件提取出来,所以看起来的话就是前面这个事件圆圈这个事件可以重复使用了,那就是所谓的非确定性宽松性。在代码当中的话,这种静邻方式调用的方法是点followed by any,也就是说只要在后边任意一个都可以,甚至可以是之前重复出现过。
07:30
所以从这里我们就可以看出来啊,这三种近邻模式。最为严格的其实就是严格精灵了,它匹配出来的事件是最少的,而宽松镜灵呢,整体来讲,因为它放宽了约束条件,中间可以插入其他事件,就可以匹配到更多的复杂事件而非确定性,宽松精灵呢,匹配到就更多了。它的。条件是最为宽松的。除了这些之外呢,在组合模式里边还可以去指定一些其他的限定条件,我们可以看到啊,除了上面提到的点next follow by follow by any之外,还可以使用其他的连接词,比如not next和not followed by,也就是加了一个取反not啊,相当于否定了,那这样的否定连接词表示什么含义呢?诶,那。
08:25
从字面上就可以看得出来啊,NEX是紧挨着,后面是什么,那note NEX呢,就是紧挨着的下一个事件不能是什么,哎,那同样道理,Not followed by,那意意思就是说。本身follow by是后边跟着什么事件,那not follow by就是后面不能跟着什么事件。这里需要注意就是note followed by,它没有严格限定,因为这个not ne的话,只要来了下一个事件,我们就能判断它到底是匹配还是不匹配了。但是not followed by来了下一个事件,如果要是刚好就是我们指定的不能出现的那个事件的话,那我们可以知道当前不匹配。
09:09
但是怎么样才叫匹配呢?诶,那我们就只好一直等下去了,只要没有出现我们指定的不能发生的那个事件,那我们就得一直等下去,流数据不停的来,那我们永远都不能保证之后永远不会出现对应我们不想要的那个事件了。所以这里需要注意就是一个模式序列,不能以not followed by这样一个连接词。对应的这样一个个体模式结束,因为你如果最后就是一个not followed by的话,比如说我们这里A。然后后边点not followed by b。那就相当于是说,只要来了A之后,那我们后面就得一直等着了啊,如果来了B啊,那当前这个不不匹配,假如没有来B的话,那我们得不停的等,不停的等来了C,来了来了E。
10:01
我们并不能判断当前匹配还是不匹配,诶,那所以这个过程就永无止境了,为了避免这种情况,当然我们就需要限定不能以note by结尾,哎,所以那不以它结尾的话表示什么含义呢?就是note follow by be,后边一定还得再跟上一个,诶,比如说后面再来一个followed by。C。那这是什么含义呢?哎,这就是表示我们必须找到一个A,然后后边再跟着一个C,而且它俩中间不能出现B。这样的话,我们就可以明确的有结束的条件,然后把当前匹配不匹配提取出来了,啊,那所以一般情况这个not followed呢,它是表示两个事件中间不会出现某种事件。那除了这些之外呢,另外还有一个比较特殊的就是时间限制within within指定的就是里边传入一个时间参数,表示限定当前我们指定的模式序列里边从第一个事件到最后一个事件。
11:11
能够允许的最大时间间隔。只有在这个时间间隔内,发生了从头到尾的所有事件,整个序列都匹配上了,这才是真正的匹配。如果说只有一部分匹配上的话,那就相当于超时了啊,就到时间的时候就是超时,未匹配是这样一种特殊的情况。啊,那当然了,呃,对于一个模式序列,很显然就只能有这样的一个时间限制,那假如说我们在代码里面多次调用了微的话,那会怎么样呢?会以最小的那个时间间隔为准。所以我们可以总结一下,看一看在模式序列里边可以定义怎么样的限制条件,比如说哎,我们前面有一个个体模式叫start,这是一个初始条件了啊呃,一个初始模式了。
12:01
初始模式后边我们可以接上一个next,这是一个严格经营条件,跟着后面一个叫做middle的个体模式。那呃,另外呢,还可以follow follow当然就是宽松了,呃,也可以follow by any,就是非确定性宽松,另外呢,还可以not next啊,后面就表示start,后面不能紧跟着对应的这个not事件。那另外呢,还可以not followed by,一个not事件,就是表示后边不能有这个事件,那所以它不能作为结束,后边我们一定还会跟着别的事件,表示start和后续事件之间不能出现这个not事件。那另外这里我们可以指定一个within within这里边给定的是一个time时间间隔,比方说我们在十秒钟之内要让之前整个的这个模式序列所有的事件都匹配到。这就是组合模式当中的一些限制条件连接词。
13:03
接下来呢,我们再来考察一下循环模式中的经营条件。之前已经说过,在个体模式当中,我们可以使用量词,然后定义出对应的一个循环模式,那假如说这里边我们有了这样一个循环模式的话,它匹配到可以匹配到多个事件,那这多个事件之间,他们彼此之间的近邻关系又是什么样的呢?哎,比如说我们说这个。a.TIMES3匹配到了一个AAA,那么这AAA它们之间能不能插入其他的事件呢?还是说它们之间就必须是一个紧挨着一个这样的严格竞定关系呢?这里我们需要注意对于定义量词的循环模式,默认情况下。采用的其实是宽松径邻的定义关系啊,也就是说当匹配直接我们定义这个A点三的时候,循环匹配的时候,AAA中间其实是可以有其他事间的,我们只要让它们是先后发生的,有这么三个A出现就可以了。
14:13
诶,这其实也就解释了,我们之前在这个代码当中啊,直接是使用点next的,点next的,我们看到这里边的这个事件,其实本身它的条件是一样的,诶那我们其实就会想到要这样说的话,是不是直接定义一个一个个体模式,然后后面直接TIMES3就完事了呢,不就相当于可以检测到三次登陆失败吗?诶但是注意这样的话,默认情况下其实是宽松敬礼。它相当于是followed by。那自然我们就想到了当前,那如果说不能是严格竞邻关系的话,那显然我们就只能是点next.ne这样做下去了,但假如说我们现在这个次数特别多,如果是连续十次登陆失败呢?那100次登录失败呢?1000次登陆失败呢?难道我们要不停的后面这个点next.next下去吗?这也太复杂了,根本没有必要吗?所以。
15:10
如果定义了循环模式,其实也是可以指定其他类型的近邻关系的,默认情况下是宽松精灵,那如果说想要让它变成一个严格精灵的话,怎么办?啊,就是这里边啊,假如说TIME3。后边可以去直接调用一个点consecut这样一个方法。连续的啊,那这样的话,当前的。个体模式,循环三次,匹配三个事件,他们就必须是严格禁令,一个挨一个,中间不能出现任何其他的事件。啊,那这就相当于完全等价于点点NEX这样一种方法啊,所以之前我们这个代码也可以写成这样的一个形式。那另外如果说我们想要。
16:01
把当前的近邻关系定义成非确定性宽松精灵,那又应该怎么样去定义呢?啊,这个也类似,就是time子后边循环模式,后边可以去再去调用一个allow combinations这样一个方法,哎,那这样的话相当于我们这里就类似于followed by any follow by any这样的三个事件的一个匹配了。这就是关于模式序列的所有的定义方式。
我来说两句