扩展AC算法的正则特性

来源:互联网 发布:淘宝店铺 关注排名 编辑:程序博客网 时间:2024/06/11 00:06

可以在AC算法上扩展的正则特性包括:“.*”,“.”,“^”,“$”等。

AC算法的查找流程:

 

 

AC算法的查找流程:

         再经过一系列有些绕的过程之后(不是扩展的重点,跳过),整个ACSM_STRUCT结构已经建立完毕。开始查找。查找伪代码:

   

 

总结一下:

1、  从状态0开始进行状态跳转。

2、  状态跳转表在search操作之前已经建立好了,在状态N下,输入字符c,跳转到状态M,按照状态跳转表来就好了。

3、  状态机到达哪些状态时发生匹配,匹配了哪些pattern,这也是之前就算出来了的。

4、  整个search操作,就是把searchbuf作为输入,在预先设计好的状态机上进行跳转,每到一个新的状态,就看一下在这个状态下有没有发生匹配,如果有就打印,如果没有就继续,直到searchbuf末尾。

 

对“.*”的扩展:

         基本思路是把包含了.*等正则特性正则表达式(ab.*cd)分成多个固定串(abcd),当固定串按照顺序或者位置依次发生匹配时,则认为整个正则表达式发生匹配了。这里的abcd在查找过程中,是按照两个独立的字符串进行查找的,但是和完全独立的两个字符串不同,abcd又同属于一个正则表达式ab.*cd,应该具备某种特定的联系。

        

         这里使用patterniid来表示这种联系。首先abcd各有一个对应的ACSM_PATTERN结构,分别进行匹配。abiid0x21??cdiid0x22??,这里要求iid的低16bit abcd相同,而又和其他的pattern区分开。而iid16~23bit表示abcd在正则表达式中出现的顺序(ab1cd2),iid24~31bit0x2)表示正则表达式被拆分成了几个固定串。

        

在匹配过程中要记录之前发生匹配的patterniid,如果低16bit相同并且高16bit不为0,则要求pattern iid16~23bit要严格递增,否则就是一个无效的匹配。当到达buf末尾时,比较pattern iid16~23bit24~31bit,只有两者相等的时候才认为整个正则表达式(ab.*cd)发生匹配了。

 

这里还有个问题,比如正则表达式abc.*bcd,而buf=”abcd”,使用上述方法你会惊奇的发现匹配发生了,而实际上没有发生匹配,原因是”abcd”可以分别匹配”abc””bcd”,并且先匹配”abc”,后匹配”bcd”,但是匹配的位置发生了重叠。所以还需要引入一个数组,记录匹配发生的结束位置。如abc发生匹配时,记录匹配发生的结束位置是3,而bcd发生匹配时,发现bcd发生匹配的起始位置是2,发生了重叠,也认为这是一个无效匹配。

 

此方法的局限性显而易见,pattern的总数不能超过2^16,每一个正则表达式被拆分之后的子pattern数不能超过2^8

 

对“.”的扩展:

         和“.*”的扩展方法类似,如正则表达式(ab…cd),被拆分成固定串abcd,但是需要在ACSM_PATTERN中增加成员变量,记录各个子pattern之间的相对位置。而在search时,只有严格按照相对位置发生的匹配才被认为是有效的匹配

 

对“^”和“$”的匹配:

         其实也比较简单,就是在search时,判断一下匹配发生起始位置和结束位置是不是buf的开头和末尾就好了

 

上述扩展不会影响search的效率,还是On)级的。

 

对“+”,“?”,“*”,“{n,m}”的扩展:

         变成Onlogn)的了,还不如找个pcreawk的源码看下了。

原创粉丝点击