00:00
我们已经了解了CP中模式API的重要概念和基本用法,那这里边我们会发现啊,因为个体模式里边可以设置量词,那就会有循环模式,而且这个循环模式呢,还可以不是特别的确定啊,比如说我们可以直接给一个one or more,或者times or more,这个时候呢,比如说我们之前说的啊,定义了一个匹配的事件是AA,后边如果加一个one or more的话。A加这样的一个判断的话,那就相当于我们可以来了一个AAA。那我们知道它就可以匹配一个,也可以匹配两个,还可以匹配三个,当然了后边的第二个和第三个也可以单独匹配,第二个本身自己也可以单独匹配,第三个也可以单独匹配,这样匹配出来的结果就会非常非常的多,有时候呢就会显得非常的冗余,哎,那所以我们就会想到,那能不能针对他这种情况去做一个精简呢?哎,当然有一种非常简单粗暴的精简方式,就是我们在这个Y帽后边加一个grareedy啊,之前我们说过啊,如果加上了grareedy的话,那就会尽可能多的去匹配更多的事件啊,这样的话就可以砍掉那些子集的匹配啊,比如说如果是one or more,然后gray的话,像刚才这种情况,那我们这个AAA来了之后,就只匹配三个A,更少的A就不再去匹配了。
01:26
但是这种方式稍微的有一点简单啊,那如果说我们想要精确去控制到底哪些应该保存,哪些应该跳过的话,那怎么样去指定这个策略呢?啊,这就涉及到CP的PAPI当中另外一个功能叫做匹配后跳过策略啊,那在源码当中叫做after match skip strategy啊,那这个策略是在哪里去配置呢?主要就是在我们定义这个初始模式的时候,调begin方法的时候,可以多传入另外一个参数。
02:00
第二个参数就是after matchkip strategy啊,我们可以看到这个源码当中啊,找一下begin,我们可以看到正常情况下只传一个string类型的字符串,表示我们第一个个体模式的名称啊,或者是传一个pattern啊,使用这个模式组的定义方式,这样都是只传一个参数就可以,那如果要是传第二个参数呢,后边跟着的就是一个after match SK strategy。而这里的这个抽象类里边,我们看到可以调用各种不同的策略方法,这里边主要就是有这么几种。当然了,最简单的有这个no skip,那就是不跳过啊,另外还有就是怎么样去跳过,指定一种跳过策略,比方说skip past last event啊,Skip to first skip to last skip to next等等等等。那接下来呢,我们就利用一个具体的事例来看一看不同的策略到底代表要做怎么样的筛选和精简。那比如说我们这里一个例子啊,呃,要检测的这个复杂事件的模式是什么呢?就是开始是一个用户名为A的事件,那我们就直接简写为事件A吧,这个事件呢,可以重复一次或多次,这是一个循环模式。
03:15
然后呢,在后边要跟着一个用户名为B的事件啊,那我们把这个就简写为事件B,所以既然是跟着一个,没有说紧跟着,所以这是一个宽松径理,他们之间可以有其他的事件。所以我们这里可以用一个类似于正则表示的那种简写形式,那就是A加,然后后边跟一个B啊,这里是不是紧跟,那就是followed by b。所以我们如果在代码当中定义的话,那就是定义一个pattern,然后首先初始模式begin给一个名称是A,那么where就是当前这个user啊,要equals a,而且它是one more,一次或多次A加。接下来呢,Followed by b where user equals BA,这就是我们代码当中的具体定义。
04:01
那这个时候我们输入了一组事件,当前的这个数据流里边啊,来了一些事件,按照先后顺序是AABAB连续来了三个A,后面一个B,当然我们知道这很明显能够跟我们定义的这个模式做一个匹配了啊,关键在于到底能匹配出多少种不同的结果。这里为了区分我们前后不同的这个A事件,就把这三个A叫做A1 a2 a3,然后后面跟一个B啊啊,那正常情况下我们知道,如果说这里不加任何的限制的话啊,默认情况下,那肯定这个Y帽就是呃,A出现一次也行,两次也行,三次都行啊,所以这里面我们就应该检测到六个匹配结果。首先我们看以A1开头的那有A1A2 a3B,因为后边只要跟着B就可以吧,然后还可以A1A2B就隔了一个A3 a1a2B也是一个匹配,另外呢,A1B也是一个匹配。当然了,A2开头的也可以有A2 a3B和A2B,最后还有A3B,所以总共是六个匹配结果。
05:06
那如果说我们觉得这个结果太多的话,那可以在这个量词one more后边直接加一个greed,定义成一个贪心匹配的策略。得到的结果那就是尽可能多的去匹配以A1作为初始条件的话,那当然就是A1 a2 a3B这三个啊最多的情况,然后接下来注意还可以以A2作为初始的事件来进行判断,那以A2开头的话,最多就是两个,所以是A2A3B,另外还有一个A3B,这样的话,每个事件作为开头只会出现一次。这是贪心进行匹配之后的结果,那我们就会想到了,这种结果就比较的单一啊,如果说我们还想进行其他的一些匹配策略的定义怎么办呢?呃,接下来我们分别来讨论一下。首先最简单的是不跳过nok,那就不用说了啊,那不跳过的话,默认策略那就是六个完整的匹配,全部输出。
06:04
然后接下来我们看跳至下一个skip to next。这个就是跳至下一个意思就是说如果找到一个A一开始的匹配,我们首先去找它的一个最大的匹配,也就是G的模式啊,按照贪心的模式去找一个它的最大匹配,然后接下来呢,就跳过它的所有剩下的匹配。直接跳至下一个A开始,也就是从A2开始继续匹配。所以我们看这个策略其实就跟greedy是非常类似的嘛,基本上就是greedy的处理策略啊,所以得到的也就是A1A2A3BA2A3B和A3B这样的三个结果。那接下来我们再来看一看其他不同的吧。接下来还有一个策略叫做跳过所有子匹配,那就是skip past last event,它会直接把所有的子匹配全部跳过去。这是什么意思呢?就是从A一开始,我们先找到一个最大的匹配a a2 a3 B,然后接下来只要是包含在这个最大匹配之内的所有的子匹配,那也就是从A1开头到A3开头的所有匹配全部跳过。
07:19
那最终得到的就只有一个啊,那所以这其实是最为精简的一种跳过策略,得到的匹配结果是最少的。那除了这些之外呢,另外还有两种跳过策略,一种叫做跳至第一个skip to first,注意这个方法呢,它里边还得传一个参数,就是指定到底要跳到哪个模式的第一个匹配事件,比方说我们传一个A,那就是要跳到A对应匹配事件的第一个,也就是说只留下A一开始的所有匹配。我们是跳至A的第一个嘛,所以就是A一开始,那么得到的就是A1A2A3BA1A2B和A1B。
08:03
选取的都是以它开头的,另外还有就是跳至最后一个skip to last,同样后边传入参数指明到底是哪个模式的最后一个。啊,那这里同样我们传入A的话,那就是找到A1开头的第一个最大化匹配,之后跳过A1和A2的所有匹配,一直跳至最后一个A事件出现的匹配,那也就是找到A3的匹配,那最终得到的呢,是A1A2A3B和A3B2个匹配。啊,所以所有的这些匹配策略啊,得到的结果可能都是不一样的,那我们在具体的代码使用的时候呢,那根据需求就可以进行灵活的定义了。那这一部分可能稍微有点复杂,但是只要是我们按照它的规则一一去分析的话,根据案例的输出结果,应该就能明确的知道他到底做的是什么。这就是整个模式API所有的内容。
我来说两句