00:00
关于Python API这一部分,最后我们再来介绍一个匹配后跳过策略,那前面介绍过程当中我们已经发现了啊,CP里边因为存在着循环模式,所谓的非确定性宽松,那同一个事件呢,有可能会重复匹配,然后分配到不同的匹配结果里面啊,那这样的话我们就知道匹配出来的数据量可能会非常非常的大,像之前我们讲到组合模式里边的这个非确定性。宽松径灵的时候,我们会发现啊,这个一组合一旦能够重复利用的时候,匹配出来的结果可能会非常的多,当然了,对于非确定性宽松径灵来讲,本来我们就是故意要放宽这个限制,要呃多做一些匹配的,那这里面我们会考虑到,那对于这个循环模式来讲,假如说匹配到了太多的情况,是不是我们就应该做一些删减呢?啊,其实对于这个循环模式有一种最好的删减。
01:03
就是greedy greedy这里边我们知道它是直接贪心嘛,尽可能多的去匹配,假如说我们是二到四次这样的一个循环匹配的话,加上GR之后,那我们就是说假如出现这个。四个aaaaa。我们知道如果不greedy的话,那相当于前两个A可以匹配。第一个到第三个,前三个A可以匹配,整个四个A又可以匹配,然后从第二个A开始呢?A,这两个A可以匹配,后边的三个A也可以匹配。从第三个A开始,后两个A还可以匹配,所以总共应该有六种匹配的结果输出。哎,那假如说我们加上了这个gray之后,那直接把那个多余的都砍掉了,直接就一个匹配输出AAA啊,那这是最简单最直接的一种精简方式。
02:00
诶,那假如说有一些场景下,我们可能会想到,我也不要让它一下子匹配那么多,呃,但是呢,也不要一下子greedy,就是直接把那么多情况全部砍掉,我们可能希望有选择的跳过某些情况,我们可能还要保留一部分扩充出来的那些匹配结果,那这种怎么样去控制呢?这在flink c里边给我们提供了一个叫做匹配跳过策略的这样一个配置。通过对于这个策略的指定,我们就可以定义到底。保留哪些匹配的结果,跳过哪些不必要的那些冗余的匹配啊,那接下来我们可以具体的说一下这里边怎么样去用这样一个策略的配置,那简单来讲的话就是在直接在这个passenger begin。定义初始模式的时候。直接传入第二个参数。
03:01
我们这里可以直接在源码里面看一眼。调用begin。我们看这里是直接传一个参数,就是一个string类型的name,表示当前第一个个体模式对应的名称,事件对应的名称啊,那这里如果说我们仔细的看一下的话,Begin这里还可以去传入第二个参数。第二个参数就是一个after match skip,也就是我们所说的。匹配之后的跳过策略啊,然后接下来我们可以看一下这个匹配之后跳过策略啊,这里边它到底可以有哪些。对应的传,呃,对应的策略可以传入,我们看到里边有很多个不同的静态方法。直观来看的话,哎,那这里边呃,首先当然有no skip啊,No skip很明显这就是不做跳过嘛,另外还有一些比如说skip to first skip to last skip to next,还有各种各样,所以接下来我们就逐一去介绍一下,利用具体的事例啊,来看一看当前这样一些。
04:14
匹配后跳过策略到底对我们的结果有什么样的影响?我们可以看这里的具体事例。首先我们先来定义一个具体的模式,这里边我们定义了一个模式序列啊,首先我们看到定A,当前第一个事件是A,然后where呢,这里定义了一个简单条件,这个条件就是要求当前的value.user就是A,哎,那所以当然当然了,选取出来就是user为A的这样一个事件。后面有一个量词one or more,所以这是一个循环模式,而这里边我们可这个A可以出现一次,也可以出现多次。后面呢,又紧跟了一个followed by,啊,这是一个宽松敬礼,后面紧跟着这个事件叫做B,那这个B呢,同样也是,就是user value user equals b叫做B的这个事件跟在后面。
05:10
那所以接下来啊,呃,我们可以想到当前这个,如果用类似于正则里边的写法的话,就可以写成A加,然后followed by b。所以接下来如果我们输入一个AAAB的话,三个A,一个B。当前我们可以得到什么样的一些匹配输出呢?这里我们注意默认情况下,我们这里边没有指定。匹配后跳过策略,那当然了,默认情况就是nok,就是不要跳过所有的事件匹配到的全部输出啊。这里我们为了区分前后不同的这个A,我们就把这三个A记成A1 a2 a3,那么对应的这里边的这个one or more,很显然就是有一个也可以,两个也行,三个也成,但所以这里我们输出的应该是六个匹配结果什么样呢?就是A1 a2 a3。
06:07
三个都匹配,这是可以的,然后A1A2是可以的,只有一个A1也是可以的,另外呢,从A2开始,把A1跳过去啊,A2开始,A2A3是可以的,然后只有一个A2也是可以的,另外呢,只有一个A3B也是可以,这就是我们完整匹配出来的六个匹配结果。那假如说我们把这个one or more后边直接加上greedy会怎么样呢?啊,那其实我们知道加上greedy之后,A1 a2a3,哎,那以A1开头的就只有这三个完整的这个匹配了,因为这是当前贪心嘛,取最多当前最多的A的个数啊,那所以就是AA2A3比。那另外A1开头我们考虑过了,A2开头也可以匹配呀,A呢,所以A2开头最多是两个,所以是A2A3B,另外还有一个是A3B,这就是每个事件作为开头啊,每一个A作为开头只会出现一次。
07:12
最终精简之后,我们就只得到了三个匹配结果。然后同样的这个例子,我们继续看其他的不同的跳过策略对最终匹配结果的一个影响,那首先是不跳过noscript nok,我们知道这是默认策略嘛,所以就是完整的六个匹配全部输出。然后接下来我们看skip to next。这个策略叫做跳至下一个。这里边我们代码调用的时候,传入的就是after match skip DR skip to next,前面我们也看到了源码里边所有的这些对应的这个静态方法返回的就是当前的类型,Skip to,呃,Last strategy啊,然后每一个对应的这个类呢,我们看它都是。
08:00
橙子,Skip to element strategy,然后最终肯定是继承after matchkip strategy,所以当前我们就实现了想要的这样的一个类啊,这样的一个对象,所以这里边我们首先看到调用的方法是这样的,那么它主要要做的事情是什么呢?跳至下一个。就是只要我们找到一个以A1起始的一个最大匹配之后,然后接下来呢,直接跳过A1,其他所有的匹配。直接考察下一个A2开始的所有匹配,哎,那所以这里面我们看到这里边有两个重要的要素,就是一个是找以每一个元素开始的匹配,另外呢,找到的是一个最大的匹配,然后就跳过其他所有匹配。啊,那所以这里我们会发现,既然是最大匹配,那这不就是graedy的那种用法吗?啊,A1找到一个A1 a2a3,这是最大匹配,然后加上B,那所以找到了这个别的都跳过,所以最终这种策略的效果跟加上GY的效果是完全等价。
09:16
那另外接下来我们再看另外一种匹配策略,叫做skip past,跳过所有子匹配这样的一个策略。这种方式呢,其实比我们前面所说的greedy还要精简的效果更好,哎,那之前我们看到greedy的话,它其实只是在当前以每一个元素开头的这种场景下贪心取最多,但是呢,每一个元素作为起始都要判断一次。那我们可能会想到,有时候我就想到了,那你这个A1A2A3 a2a三都已经出现过了,那我接下来就不要再以A2A3再去做匹配了,诶那怎么样能够把它也全跳过呢?那就用当前的这种匹配策略。
10:04
跳过所有匹配。如果用它的话,那就是只要找到一个A一开始的最大匹配之后,接下来直接跳过所有元素A1到A3的开头的所有匹配,相当于就是把剩下的所有子匹配全部跳过,直接得到一个A1 a2 a3B,这就是最为精简的一个跳舞策略,得到的匹配是最少的。最经典的。那剩下的还有一些匹配策略,比如说这里有跳至第一个和跳至最后一个,那首先我们来看跳至第一个skip to first,后面呢,还有一个A,这里我们看到这里它是需要传入一个参数的,它表示什么含义呢?哎,就是表示指明到底要跳到哪一个个体模式对应的第一个匹配事件。那比如说这里我们传入的是A啊,那所以就是说找到一个A,一开始的匹配,首先我们是按照最大的先去匹配啊,找到A1 a2a3之后直接跳到。
11:12
以最开始的first嘛,就是第一个A为开始的匹配,所以相当于呢,就是每次我们都跳到以第一个AA一开始的那个匹配,那相当于最终我们就只留下A一开始的匹配。所以这里面我们最终得到的是A1A2A3BAA1A2BA1BA,也就是把剩下A2A3作为起始的那些匹配全部跳过了。那类似的还有一个策略,叫做跳至最后一个skip to last,然后同样也要传一个参数,我们这里传入A的话,诶,那就是指明了当前找到了A1A2A3B这样一个以A一开始的最大匹配之后。接下来呢,是要。跳至最后一个A,也就是跳至A3开始的匹配,那接下来当然就是把A1A2的所有开始的所有匹配全部跳过了啊,那我们最终得到的就是A1 a2 a3B和A3B。
12:16
那在实际的项目应用场景里边,这就要根据我们具体的需求,可以去选择各种不同的匹配后跳过策略,这样的话就可以针对我们的匹配结果做一个精简或者做一个扩充,这就是关于这一部分模式API的完整介绍。
我来说两句