发明内容
本发明实施例提供一种正则表达式匹配方法及装置,用以解决正则表达式匹配速度较慢的问题。
第一方面,提供一种正则表达式匹配方法,包括:
确定正则表达式的指纹;
根据所述正则表达式的指纹,确定所述正则表达式的代表指纹;
根据所述正则表达式的代表指纹,确定正则表达式组,并确定所述正则表达式组的代表指纹;
基于所述正则表达式组的代表指纹与所述正则表达式组编译成的确定有限状态自动机DFA的对应关系,对待匹配数据进行正则表达式匹配。
结合第一方面,在第一方面的第一种实现方式中,所述确定正则表达式的指纹,具体包括:
提取正则表达式的必经字符串,并截取预设长度的所述必经字符串作为所述正则表达式的指纹;所述必经字符串为能够匹配上所述正则表达式的数据中都包含的字符串。
结合第一方面的第一种实现方式,在第一方面的第二种实现方式中,所述提取正则表达式的必经字符串,具体包括:
当正则表达式中至少包含嵌套元字符时,若最外层嵌套元字符中不包含分支元字符,且最外层嵌套元字符后没有重复元字符,则提取删除所述正则表达式的最外层嵌套元字符后的正则表达式的必经字符串,作为所述正则表达式的必经字符串;
当正则表达式中至少包含嵌套元字符和分支元字符时,若任何嵌套元字符中均不包含分支元字符,或仅最外层嵌套元字符包含分支元字符,确定所述正则表达式包括的不包含分支元字符的分支正则表达式;提取所述分支正则表达式的必经字符串;确定所述正则表达式的必经字符串为所有分支正则表达式的必经字符串中都包含的字符串;
当正则表达式中至少包含嵌套元字符、分支元字符和重复元字符时,若任何嵌套元字符中均不包含重复元字符,确定所述正则表达式包括的不包含分支元字符的分支正则表达式;提取所述分支正则表达式的必经字符串;确定所述正则表达式的必经字符串为所有分支正则表达式的必经字符串。
结合第一方面或者第一方面的第一种实现方式或者第一方面的第二种实现方式,在第一方面的第三种实现方式中,所述根据所述正则表达式的指纹,确定所述正则表达式的代表指纹,具体包括:
将所述正则表达式的指纹进行哈希,选择哈希冲突最小的指纹作为所述正则表达式的代表指纹。
结合第一方面或者第一方面的第一种实现方式或者第一方面的第二种实现方式或者第一方面的第三种实现方式,在第一方面的第四种实现方式中,所述根据所述正则表达式的代表指纹,确定正则表达式组,具体包括:
根据所述正则表达式的代表指纹的哈希值,将所述正则表达式放入哈希槽中,并判断放入的哈希槽中是否已存在正则表达式;
在放入的哈希槽中已存在正则表达式时,若所述正则表达式的代表指纹和已存在正则表达式的代表指纹相同,则将所述正则表达式和已存在正则表达式合并为一个正则表达式组。
结合第一方面的第四种实现方式,在第一方面的第五种实现方式中,所述将所述正则表达式和已存在正则表达式合并为一个正则表达式组之前,还包括:
判断所述正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量是否超过预设阈值;
所述将所述正则表达式和已存在正则表达式合并为一个正则表达式组,具体包括:
在所述正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量不超过预设阈值时,将所述正则表达式和已存在正则表达式合并为一个正则表达式组。
结合第一方面或者第一方面的第一种实现方式或者第一方面的第二种实现方式或者第一方面的第三种实现方式或者第一方面的第四种实现方式或者第一方面的第五种实现方式,在第一方面的第六种实现方式中,所述确定所述正则表达式组的代表指纹,具体包括:
将所述正则表达式组的指纹进行哈希,选择哈希值在所有正则表达式组的代表指纹的哈希值中出现次数最少的指纹作为所述正则表达式组的代表指纹。
第二方面,提供一种正则表达式匹配装置,包括:
第一确定单元,用于确定正则表达式的指纹;
第二确定单元,用于根据所述正则表达式的指纹,确定所述正则表达式的代表指纹;
第三确定单元,用于根据所述正则表达式的代表指纹,确定正则表达式组,并确定所述正则表达式组的代表指纹;
匹配单元,用于基于所述正则表达式组的代表指纹与所述正则表达式组编译成的确定有限状态自动机DFA的对应关系,对待匹配数据进行正则表达式匹配。
结合第二方面,在第二方面的第一种实现方式中,所述第一确定单元,具体用于提取正则表达式的必经字符串,并截取预设长度的所述必经字符串作为所述正则表达式的指纹;所述必经字符串为能够匹配上所述正则表达式的数据中都包含的字符串。
结合第二方面的第一种实现方式,在第二方面的第二种实现方式中,所述第一确定单元,具体用于当正则表达式中至少包含嵌套元字符时,若最外层嵌套元字符中不包含分支元字符,且最外层嵌套元字符后没有重复元字符,则提取删除所述正则表达式的最外层嵌套元字符后的正则表达式的必经字符串,作为所述正则表达式的必经字符串;
当正则表达式中至少包含嵌套元字符和分支元字符时,若任何嵌套元字符中均不包含分支元字符,或仅最外层嵌套元字符包含分支元字符,确定所述正则表达式包括的不包含分支元字符的分支正则表达式;提取所述分支正则表达式的必经字符串;确定所述正则表达式的必经字符串为所有分支正则表达式的必经字符串中都包含的字符串;
当正则表达式中至少包含嵌套元字符、分支元字符和重复元字符时,若任何嵌套元字符中均不包含重复元字符,确定所述正则表达式包括的不包含分支元字符的分支正则表达式;提取所述分支正则表达式的必经字符串;确定所述正则表达式的必经字符串为所有分支正则表达式的必经字符串。
结合第二方面或者第二方面的第一种实现方式或者第二方面的第二种实现方式,在第二方面的第三种实现方式中,所述第二确定单元,具体用于将所述正则表达式的指纹进行哈希,选择哈希冲突最小的指纹作为所述正则表达式的代表指纹。
结合第二方面或者第二方面的第一种实现方式或者第二方面的第二种实现方式或者第二方面的第三种实现方式,在第二方面的第四种实现方式中,所述第三确定单元,具体用于根据所述正则表达式的代表指纹的哈希值,将所述正则表达式放入哈希槽中,并判断放入的哈希槽中是否已存在正则表达式;在放入的哈希槽中已存在正则表达式时,若所述正则表达式的代表指纹和已存在正则表达式的代表指纹相同,则将所述正则表达式和已存在正则表达式合并为一个正则表达式组。
结合第二方面的第四种实现方式,在第二方面的第五种实现方式中,所述第三确定单元,还用于将所述正则表达式和已存在正则表达式合并为一个正则表达式组之前,判断所述正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量是否超过预设阈值;
所述第三确定单元,具体用于在所述正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量不超过预设阈值时,将所述正则表达式和已存在正则表达式合并为一个正则表达式组。
结合第二方面或者第二方面的第一种实现方式或者第二方面的第二种实现方式或者第二方面的第三种实现方式或者第二方面的第四种实现方式或者第二方面的第五种实现方式,在第二方面的第六种实现方式中,所述第三确定单元,具体用于将所述正则表达式组的指纹进行哈希,选择哈希值在所有正则表达式组的代表指纹的哈希值中出现次数最少的指纹作为所述正则表达式组的代表指纹。
根据第一方面提供的正则表达式匹配方法,第二方面提供的正则表达式匹配装置,基于正则表达式的指纹对正则表达式进行分组,而一个正则表达式可以具有多个指纹,因此,相比于现有技术,基于正则表达式的指纹进行分组可以得到数量较少的正则表达式组,即正则表达式组编译成的DFA的数量也较少,可以提高正则表达式匹配速度,并且不会占用大量的存储空间。
具体实施方式
为了给出提高正则表达式匹配速度的实现方案,本发明实施例提供了一种正则表达式匹配方法及装置,以下结合说明书附图对本发明的优选实施例进行说明,应当理解,此处所描述的优选实施例仅用于说明和解释本发明,并不用于限定本发明。并且在不冲突的情况下,本申请中的实施例及实施例中的特征可以相互组合。
本发明实施例提供一种正则表达式匹配方法,如图1所示,包括:
步骤101、确定正则表达式的指纹;
步骤102、根据该正则表达式的指纹,确定该正则表达式的代表指纹;
步骤103、根据该正则表达式的代表指纹,确定正则表达式组,并确定该正则表达式组的代表指纹;
步骤104、基于该正则表达式组的代表指纹与该正则表达式组编译成的确定有限状态自动机DFA的对应关系,对待匹配数据进行正则表达式匹配。
可见,上述正则表达式匹配方法是基于正则表达式的指纹对正则表达式进行分组,由于每个正则表达式可以具有多个指纹,因此,基于正则表达式的指纹进行分组得到的正则表达式组的数量较少,即正则表达式组编译成的DFA数量较少,即采用上述正则表达式匹配方法,不但能够提高正则表达式的匹配速度,还能够节省存储空间。
进一步的,正则表达式的指纹为预设长度的字符串,且该预设长度的字符串包含在能够和该正则表达式匹配的所有数据中,因此,上述步骤101确定正则表达式的指纹,具体可以包括:提取正则表达式的必经字符串,并截取预设长度的该必经字符串作为该正则表达式的指纹;该必经字符串为能够匹配上该正则表达式的数据中都包含的字符串。
上述提取正则表达式的必经字符串,具体可以包括:
当正则表达式中至少包含嵌套元字符时,若最外层嵌套元字符中不包含分支元字符,且最外层嵌套元字符后没有重复元字符,则提取删除该正则表达式的最外层嵌套元字符后的正则表达式的必经字符串,作为该正则表达式的必经字符串;
当正则表达式中至少包含嵌套元字符和分支元字符时,若任何嵌套元字符中均不包含分支元字符,或仅最外层嵌套元字符包含分支元字符,确定该正则表达式包括的不包含分支元字符的分支正则表达式;提取该分支正则表达式的必经字符串;确定该正则表达式的必经字符串为所有分支正则表达式的必经字符串中都包含的字符串;
当正则表达式中至少包含嵌套元字符、分支元字符和重复元字符时,若任何嵌套元字符中均不包含重复元字符,确定该正则表达式包括的不包含分支元字符的分支正则表达式;提取该分支正则表达式的必经字符串;确定该正则表达式的必经字符串为所有分支正则表达式的必经字符串;
其它情况不再一一列举。
其中,分支正则表达式的必经字符串为能够匹配上该分支正则表达式的数据中都包含的字符串。
进一步的,步骤102根据正则表达式的指纹,确定该正则表达式的代表指纹,可以从该正则表达式的所有指纹中随机选择一个指纹作为该正则表达式的代表指纹。较佳的,可以将该正则表达式的指纹进行哈希,选择哈希冲突最小的指纹作为该正则表达式的代表指纹。
选择哈希冲突最小的指纹作为正则表达式的代表指纹,能够在正则表达式分组时,尽量避免哈希冲突,使代表指纹的哈希值相同的正则表达式尽量合并为一个正则表达式组,因此能够减少正则表达式组的数量,从而减少编译成的DFA的数量,提高正则表达式的匹配速度。
进一步的,步骤103根据正则表达式的代表指纹,确定正则表达式组,具体包括:根据该正则表达式的代表指纹的哈希值,将该正则表达式放入哈希槽中,并判断放入的哈希槽中是否已存在正则表达式;在放入的哈希槽中已存在正则表达式时,若该正则表达式的代表指纹和已存在正则表达式的代表指纹相同,则将该正则表达式和已存在正则表达式合并为一个正则表达式组。
较佳的,在合并之前,还可以考虑到正则表达式组编译成的DFA的大小,为避免编译成的DFA过大,具体可以在将该正则表达式和已存在正则表达式合并为一个正则表达式组之前,判断该正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量是否超过预设阈值;在该正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量不超过预设阈值时,才将该正则表达式和已存在正则表达式合并为一个正则表达式组。
由于正则表达式组编译成的DFA过大时不但会占用较大的存储空间,更会降低后续正则表达式匹配时的匹配速度,因此,采用在该正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量不超过预设阈值时,才将该正则表达式和已存在正则表达式合并为一个正则表达式组的方案,不但能够节省正则表达式组编译成的DFA占用的存储空间,更能够提高正则表达式的匹配速度。
较佳的,步骤103确定正则表达式组的代表指纹,具体包括:将该正则表达式组的指纹进行哈希,选择哈希值在所有正则表达式组的代表指纹的哈希值中出现次数最少的指纹作为该正则表达式组的代表指纹。
选择哈希值在所有正则表达式组的代表指纹的哈希值中出现次数最少的指纹作为该正则表达式组的代表指纹,即可以使各正则表达式组的代表指纹的哈希值尽量不同,使各正则表达式组尽量放入不同的哈希槽中,进行正则表达式的匹配时,能够提高配速度。
较佳的,在执行步骤104对待匹配数据进行正则表达式匹配之前,还可以对各正则表达式组进行合并调整,以进一步减少正则表达式组的数量,该合并调整步骤具体可以包括:
合并具有相同代表指纹的不同正则表达式组,合并后的正则表达式组的代表指纹为该相同代表指纹;
合并具有至少指定数量个相同指纹的不同正则表达式组,并确定该合并后的正则表达式组的代表指纹。
较佳的,在合并不同正则表达式组之前,也可以考虑到正则表达式组编译成的DFA的大小,具体可以在合并不同正则表达式组之前,判断合并后的正则表达式组编译成的DFA状态数量是否超过预设阈值;在合并后的正则表达式组编译成的DFA状态数量不超过预设阈值时,才将该不同正则表达式组合并为一个正则表达式组。
通过对符合条件的不同正则表达式组进行合并,可以进一步减少正则表达式组的数量,进而可以减少编译成的DFA的数量,因此,可以进一步提高正则表达式的匹配速度。
本发明实施例提供的正则表达式匹配方法可应用于深度包检测(Deeppacket inspection,DPI)、文本匹配、文档内容检索等领域。
即本发明实施例提供的正则表达式匹配方法需要先基于正则表达式的指纹对正则表达式进行分组,确定各正则表达式组后,将每个正则表达式组编译成一个DFA,建立正则表达式组的代表指纹与DFA的对应关系。
下面结合附图,用具体实施例对本发明提供的正则表达式匹配方案进行详细描述。
图2所示为本发明实施例提供的正则表达式匹配方法的详细流程图,具体包括:
步骤201、确定各正则表达式的所有指纹。
具体为先提取正则表达式的必经字符串,再截取预设长度的该必经字符串作为该正则表达式的指纹。
由于正则表达式的多样化,包含的情况较多,下面列举一些情况,结合具体例子说明如何确定正则表达式的指纹,在以下例子中,指纹的长度即预设长度具体为3。
例1:正则表达式“a(bcd)ef”,包含一层嵌套元字符“()”,这层嵌套元字符中不包含分支元字符“|”,且后面也没有重复元字符,故可以将嵌套元字符“()”删除后得到正则表达式“a(bcd)ef”的必经字符串“abcdef”,因此,正则表达式“a(bcd)ef”的指纹为“abc”、“bcd”、“cde”和“def”。
例2:正则表达式“abc+de”,包含重复元字符“+”,表示字符“c”重复一次或多次。在提取正则表达式“abc+de”的必经字符串时,可以将正则表达式“abc+de”拆分为两个分支正则表达式“abc”和“cde”,分支正则表达式“abc”的必经字符串即为“abc”,分支正则表达式“cde”的必经字符串即为“cde”,正则表达式“abc+de”的必经字符串即为“abc”和“cde”,因此,正则表达式“abc+de”的指纹为“abc”和“cde”。
例3:正则表达式“a(bc)+f”,包含嵌套元字符“()”、重复元字符“+”,表示字符串“bc”重复一次或多次。和例2类似,在提取正则表达式“a(bc)+f”的必经字符串时,可以将正则表达式“a(bc)+f”拆分为两个分支正则表达式“a(bc)”和“(bc)f”。和例1类似,可以删去两个分支正则表达式中的嵌套元字符“()”,得到“abc”和“bcf”,分支正则表达式“a(bc)”的必经字符串即为“abc”,分支正则表达式“(bc)f”的必经字符串即为“bcf”,正则表达式“a(bc)+f”的必经字符串即为“abc”和“bcf”,因此,正则表达式“a(bc)+f”的指纹为“abc”和“bcf”。
例4:正则表达式“aed(bc)*fac”,包含嵌套元字符“()”、重复元字符“*”,表示字符串“bc”重复零次或多次。在提取正则表达式“aed(bc)*fac”的必经字符串时,可以将正则表达式“aed(bc)*fac”拆分为两个分支正则表达式“aed”和“fac”,分支正则表达式“aed”的必经字符串即为“aed”,分支正则表达式“fac”的必经字符串即为“fac”,正则表达式“aed(bc)*fac”的必经字符串即为“aed”和“fac”,因此,正则表达式“aed(bc)*fac”的指纹为“aed”和“fac”。
对于包含重复元字符“?”以及包含重复元字符“{,m}”的正则表达式和例4类似,在此不再详述。
例5:正则表达式“ab{5,}c”,包含重复元字符“{n,}”,表示字符“b”重复至少五次。在提取正则表达式“ab{5,}c”的必经字符串时,可以将正则表达式“ab{5,}c”拆分为两个分支正则表达式“abbbbb”和“bbbbbc”,分支正则表达式“abbbbb”的必经字符串即为“abbbbb”,分支正则表达式“bbbbbc”的必经字符串即为“bbbbbc”,正则表达式“ab{5,}c”的必经字符串即为“abbbbb”和“bbbbbc”,因此,正则表达式“ab{5,}c”的指纹为“abb”、“bbb”和“bbc”。
上述例5中,若设置了必经字符串的长度阈值k,当n>k时,将前面的字符或子表达式重复k次即可。
对于包含重复元字符“{n,m}”的正则表达式和例5类似,在此不再详述。
例6:正则表达式“accde|accbf”,包含分支元字符“|”。在提取正则表达式“accde|accbf”的必经字符串时,可以将正则表达式“accde|accbf”拆分为两个分支正则表达式“accde”和“accbf”,分支正则表达式“accde”的必经字符串即为“accde”,分支正则表达式“accbf”的必经字符串即为“accde”,正则表达式“accde|accbf”的必经字符串为“accde”和“accde”中都包含的字符串,即“acc”,因此,“accde|accbf”的指纹为“acc”。
例7:正则表达式“abc[aeiou]fg”,包含元字符“[]”,表示匹配任何一个英文元音字母。在提取正则表达式“abc[aeiou]fg”的必经字符串时,可以将正则表达式“abc[aeiou]fg”拆分为两个分支正则表达式“abc”和“fg”,分支正则表达式“abc”的必经字符串即为“abc”,分支正则表达式“fg”的必经字符串即为“fg”,正则表达式“abc[aeiou]fg”的必经字符串为“abc”和“fg”中都包含的字符串,因此,正则表达式“abc[aeiou]fg”不存在指纹。
例8:正则表达式“ca(bcd|bed)f”,包含一层嵌套元字符“()”,在这一层嵌套元字符“()”中包含分支元字符“|”。在提取正则表达式“ca(bcd|bed)f”的必经字符串时,可以将正则表达式“ca(bcd|bed)f”拆分为两个分支正则表达式“ca(bcd)f”和“ca(bde)f”。和例1类似,可以删去两个分支正则表达式中的嵌套元字符“()”,得到“cabcdf”和“cabdef”。分支正则表达式“ca(bcd)f”的必经字符串即为“cabcdf”,分支正则表达式“ca(bde)f”的必经字符串即为“cabdef”,正则表达式“ca(bcd|bed)f”的必经字符串为“cabcdf”和“cabdef”中都包含的字符串,即“cab”,因此,正则表达式“ca(bcd|bed)f”的指纹为“cab”。
例9:正则表达式“aab((ce){2,3}d|cd)+bex”,包含两层嵌套元字符,并具有多种需要按不同情况处理的元字符。首先根据重复元字符“+”,将其拆分为两个分支正则表达式“aab((ce){2,3}d|cd)”和“((ce){2,3}d|cd)bex”;
其中分支正则表达式“aab((ce){2,3}d|cd)”可再拆分为“aab((ce){2,3}d)”和“aab(cd)”,删除“aab((ce){2,3}d)”和“aab(cd)”中的最外层嵌套元字符“()”,得到“aab(ce){2,3}”和“aabcd”;
上述“aab(ce){2,3)”可再拆分为“aabcece”和“cece”;“aabcece”的必经字符串即为“aabcece”,“cece”的必经字符串即为“cece”,“aab(ce){2,3}”的必经字符串即为“aabcece”和“cece”;
上述“aabcd”的必经字符串即为“aabcd”;
分支正则表达式“aab((ce){2,3}d|cd)”的必经字符串为“aab(ce){2,3}”的必经字符串和“aabcd”的必经字符串中都包含的字符串,即“aabc”;
另一分支正则表达式“((ce){2,3}d|cd)bex”可拆分为“((ce){2,3}d)bex”和“(cd)bex”,删除“((ce){2,3}d)bex”和“(cd)bex”中的最外层嵌套元字符“()”,得到“(ce){2,3}dbex”和“cdbex”;
上述“(ce){2,3}dbex”可再拆分为“cece”和“cecedbex”;“cece”的必经字符串即为“cece”,“cecedbex”的必经字符串即为“cecedbex”,“(ce){2,3}dbex”的必经字符串即为“cece”和“cecedbex”;
上述“cdbex”的必经字符串即为“cdbex”;
分支正则表达式“((ce){2,3}d|cd)bex”的必经字符串为“(ce){2,3}dbex”的必经字符串和“cdbex”的必经字符串中都包含的字符串,即“dbex”;
正则表达式“aab((ce){2,3}d|cd)+bex”的必经字符串为分支正则表达式“aab((ce){2,3}d|cd)”和“((ce){2,3}d|cd)bex”的所有必经字符串,即“aabc”和“dbex”,因此,正则表达式“aab((ce){2,3}d|cd)+bex”的指纹为“aab”、“abc”、“bde”和“bex”。
上述正则表达式拆分后的分支正则表达式并不一定跟原始的正则表达式有完全相同的语义,只要分支正则表达式能涵括所有必经字符串即可。
步骤202、确定各正则表达式的代表指纹。
具体可以将正则表达式的各指纹进行哈希,选择和其它正则表达式的代表指纹哈希冲突最小的指纹作为该正则表达式的代表指纹。
步骤203、对正则表达式进行预分组,将具有相同代表指纹的正则表达式分为一个正则表达式组。
较佳的,可以在正则表达式组编译成的DFA的状态的数量不超过预设阈值的前提条件下,对正则表达式进行预分组。
得到的正则表达式组中的各个正则表达式具有的所有相同指纹为该正则表达式组的指纹。
在本发明实施例中,正则表达式的预分组具体可以在哈希表中实现,具体实现流程如图3所示,包括:
步骤301、将当前正在进行处理的正则表达式看作一个仅包含一个正则表达式的正则表达式组,当前正在进行处理的正则表达式的代表指纹作为该正则表达式组的预分组指纹。
为便于区分,该正则表达式组下文中称为当前正则表达式组。
步骤302、判断该哈希槽中是否存在其它正则表达式组。
若确定该哈希槽中存在其它正则表达式组,则进入步骤303;若确定该哈希槽中不存在其它正则表达式组,则该哈希槽原为一个空槽,结束本次流程。
步骤303、判断该其它正则表达式组中是否存在预分组指纹和当前正则表达式组的预分组指纹相同的指定正则表达式组。
若确定该其它正则表达式组中存在预分组指纹和当前正则表达式组的预分组指纹相同的指定正则表达式组,则进入步骤304;若确定该其它正则表达式组中不存在预分组指纹和当前正则表达式组的预分组指纹相同的指定正则表达式组,则结束本次流程。
步骤304、判断当前正则表达式组和该指定正则表达式组合并后的正则表达式组编译成的DFA的状态的数量是否会超过预设阈值。
若确定当前正则表达式组和该指定正则表达式组合并后的正则表达式组编译成的DFA的状态的数量不会超过预设阈值,则进入步骤305,若确定当前正则表达式组和该指定正则表达式组合并后的正则表达式组编译成的DFA的状态的数量会超过预设阈值,则结束本次流程。
步骤305、将当前正则表达式组和该指定正则表达式组进行合并,合并后的正则表达式组的预分组指纹为当前正则表达式组和该指定正则表达式组具有的相同的预分组指纹。
下面用具体例子对上述预分组流程进行说明:
假设对10个正则表达式r1、r2……r10进行预分组,经过步骤201确定的各正则表达式r1、r2……r10的指纹如下表所示:
正则表达式 |
指纹 |
r1 |
abc,efg |
r2 |
abc,efg |
r3 |
lmn,opq |
r4 |
lmn,opq |
r5 |
abc,hij |
r6 |
abc,efg,hij |
r7 |
opq,rst |
r8 |
opq,rst |
r9 |
uvw |
r10 |
uvw |
假设各指纹经过哈希计算得到的哈希值如下表所示:
指纹 |
哈希值 |
abc |
0 |
efg |
4 |
hij |
2 |
lmn |
2 |
opq |
7 |
rst |
5 |
uvw |
4 |
针对每个正则表达式,选择一个指纹作为该正则表达式的代表指纹,根据该代表指纹的哈希值将该正则表达式放入对应的哈希槽中。在本例子中,哈希值N对应的哈希槽即为哈希槽N,N=1、2……9。
依次将10个正则表达式r1、r2……r10放入哈希表中,对于第一个正则表达式r1,可以选择“abc”作为正则表达式r1的代表指纹,对应的哈希值为0,将正则表达式r1放入哈希槽0中,原哈希槽0为一个空槽;对于第二个正则表达式r2,也可以选择“abc”作为正则表达式r2的代表指纹,也将正则表达式r2放入哈希槽0中,由于正则表达式r1和正则表达式r2的代表指纹相同,并且假设正则表达式r1和正则表达式r2构成的正则表达式组编译成的DFA的状态的数量不会超过预设阈值,因此可以将正则表达式r1和正则表达式r2放入一个正则表达式组内,构成正则表达式组g1,预分组指纹为“abc”。同理可以将正则表达式r3和正则表达式r4放入哈希槽2中,正则表达式r3和正则表达式r4构成正则表达式组g2,预分组指纹为“lmn”,对应的哈希值为2。在将正则表达式r5放入哈希表时,可以选择“hij”作为代表指纹,但“hij”对应的哈希值也为2,此时会和哈希槽2中正则表达式组g2的预分组指纹产生哈希冲突,即和正则表达式组g2中正则表达式的代表指纹产生哈希冲突,因此较佳的,选择“abc”作为代表指纹,将该正则表达式r5也放入哈希槽0中,正则表达式r5的代表指纹和哈希槽0中的正则表达式组g1的预分组指纹相同,即和正则表达式组g1中的正则表达式的代表指纹相同,均为“abc”,但此时假设正则表达式r5和正则表达式组g1合并为一个正则表达式组后编译成的DFA的状态的数量会超过预设阈值,因此不能进行合并。
假设经过预分组后,得到的哈希表如下所示:
哈希值 |
正则表达式组:预分组指纹 |
0 |
g1:abc;g3:abc; |
1 |
|
2 |
g2:lmn |
3 |
|
4 |
g5:uvw |
5 |
|
6 |
|
7 |
g4:opq |
8 |
|
9 |
|
其中,各正则表达式组包含的正则表达式及具有的指纹如下表所示:
正则表达式组 |
正则表达式 |
指纹 |
g1 |
r1,r2 |
abc,efg |
g2 |
r3,r4 |
lmn,opq |
g3 |
r5,r6 |
abc,hij |
g4 |
r7,r8 |
opq,rst |
g5 |
r9,r10 |
uvw |
经过步骤203,所有正则表达式均放入哈希表中,但此时,正则表达式的分组不一定是最优的。
步骤204、确定各正则表达式组的代表指纹。
代表指纹的确定原则实质为使各正则表达式组的代表指纹的哈希值尽量不同。如果不能避免互不相同,则使哈希值相同的情况出现尽量少。
在上述203所举的例子中,将10个正则表达式r1、r2……r10均放入哈希表中,构成5个正则表达式组g1、g2……g5,使各正则表达式组的代表指纹的哈希值尽量不同,即使不同的正则表达式组尽量放入不同的哈希槽内,可以通过对步骤203例子中生成的哈希表进行迭代调整实现。
在本发明实施例中可以把步骤203例子中生成的哈希表抽象成一个有向图G(V,E),其中V是哈希槽的集合,V={vi|vi是一个哈希槽,i=1,…,n,n是哈希表的总槽数},E是两个哈希槽之间的关系的集合,若<v1,v2>∈E,则<v1,v2>在有向图上表现为从哈希槽v1到哈希槽v2的一条边,它的实际含义为哈希槽v1中的正则表达式组具有的所有指纹中,存在至少一个指纹通过哈希函数可以映射到哈希槽v2,称v1为尾,称v2为头。以哈希槽vi为头的边的数目称为哈希槽vi的入度,记为ID(vi),以哈希槽vi为尾的边的数目称为哈希槽vi的出度,记为OD(vi)。对于OD(vi)=0的哈希槽vi分为如下两种情况:
情况1、哈希槽vi中存在正则表达式组,但这些正则表达式组不存在通过哈希函数可以映射到除哈希槽vi之外的其它哈希槽的指纹;
情况2、哈希槽vi中不存正则表达式分组,即哈希槽vi为空槽。
有向图G(V,E)中,从哈希槽v到哈希槽v'的路径是一个哈希槽的序列(v=vi, 0,vi,1,…,vi,m=v'),其中<vi,j-1,vi,j>∈E,1≤j≤m,m为设定的路径最大长度,路径的长度是路径上的边的数目。
因此对步骤203例子中生成的哈希表进行迭代调整具体可以为:
对于存在多个正则表达式组的哈希槽vi,在有向图G(V,E)中查找哈希槽vi到哈希槽vj的路径(vi=vi,0,vi,1,…,vi,m=vj),并且vj为空槽。如果查找到哈希槽vj,就可以把哈希槽vi,k中的相应正则表达式组调整到槽vi,k+1,0≤k≤m-1,如此,哈希槽vi中的正则表达式组就减少了一个。
由步骤203例子中生成的哈希表构建的有向图如图4所示,对于存在两个正则表达式组的哈希槽0,在有向图中查找路径,查找到路径(0,4),但哈希槽4并非空槽,不满足要求;查找到路径(0,2,7,5),哈希槽5为空槽,满足要求,可以进行调整。因此,将正则表达式组g4调整到哈希槽5,确定正则表达式组g4的代表指纹为“rst”;将正则表达式组g2调整到哈希槽7,确定正则表达式组g2的代表指纹为“opq”;将正则表达式组g3调整到哈希槽2,确定正则表达式组g3的代表指纹为“hij”。而对于正则表达式组g1和正则表达式组g5,存放位置无需进行调整,因此,正则表达式组的预分组指纹即为该正则表达式组的代表指纹。
经过迭代调整后得到的哈希表如下所示:
哈希值 |
正则表达式组:代表指纹 |
0 |
g1:abc |
1 |
|
2 |
g3:hij |
3 |
|
4 |
g5:uvw |
5 |
g4:rst |
6 |
|
7 |
g2:opq |
8 |
|
9 |
|
步骤205、对各正则表达式组进行合并调整,具体可以包括如下两种方式:
方式一:在合并后的正则表达式组编译成的DFA的状态的数量不超过预设阈值的前提下,将具有相同代表指纹的不同正则表达式组合并为一个正则表达式组;此时将该相同代表指纹作为合并后的正则表达式组的代表指纹;
方式二:在合并后的正则表达式组编译成的DFA的状态的数量不超过预设阈值的前提下,将具有至少指定数量个相同指纹的不同正则表达式组合并为一个正则表达式组;此时在该不同正则表达式组具有的所有相同指纹中,确定出一个合并后的正则表达式组的代表指纹,该代表指纹的哈希值相比于其它相同指纹的哈希值,在其它正则表达式组的代表指纹的哈希值中出现的次数最少。在本发明实施例中,上述指定数量具体可以为两个。
上述方式二的合并调整步骤也可以直接在预分组之后进行。
较佳的,在将不同正则表达式组合并为一个正则表达式组时还可以考虑到和其它正则表达式组的代表指纹的哈希值的冲突问题,进一步增加如下合并条件:
不同正则表达式组的相同的指纹中存在指纹的哈希值和其它正则表达式组的代表指纹的哈希值均不相同,即该不同正则表达式组的相同的指纹中存在指纹可以映射到空的哈希槽;或者不同正则表达式组的相同的指纹中存在指纹的哈希值和该不同正则表达式组中的一个正则表达式组的代表指纹的哈希值相同,即该不同正则表达式组的相同的指纹中存在指纹可以映射到该不同正则表达式组中的一个正则表达式组原本所在的哈希槽。
步骤206、将各正则表达式组编译成一个DFA,建立各正则表达式组的代表指纹与DFA的对应关系。
步骤207、基于该对应关系,对待匹配数据进行正则表达式匹配,其具体流程如图5所示,包括:
步骤501、确定待匹配数据中所包含的正则表达式组的代表指纹;
步骤502、确定待匹配数据中所包含的正则表达式组的代表指纹对应的DFA;
步骤503、根据确定的DFA,对待匹配数据进行正则表达式匹配。
综上所述,本发明实施例提供的正则表达式匹配方法,基于正则表达式的指纹对正则表达式进行分组,可以得到数量较少的正则表达式组,进而得到数量较少的DFA;通过对符合条件的不同正则表达式组进行合并调整,可以进一步减少正则表达式组的数量,进而进一步减少DFA的数量;并且,在确定正则表达式组和合并不同正则表达式组时,均考虑到了得到的正则表达式组编译成的DFA的状态的数量,避免了正则表达式组编译成的DFA过大;因此,采用本发明实施例提供的方法,不但能够提高正则表达式的匹配速度,并且能够节省存储资源。
基于同一发明构思,根据本发明上述实施例提供的正则表达式匹配方法,相应地,本发明实施例还提供一种正则表达式匹配装置,其结构示意图如图6所示,具体包括:
第一确定单元601,用于确定正则表达式的指纹;
第二确定单元602,用于根据该正则表达式的指纹,确定该正则表达式的代表指纹;
第三确定单元603,用于根据该正则表达式的代表指纹,确定正则表达式组,并确定该正则表达式组的代表指纹;
匹配单元604,用于基于该正则表达式组的代表指纹与该正则表达式组编译成的确定有限状态自动机DFA的对应关系,对待匹配数据进行正则表达式匹配。
可见,采用本发明实施例提供的正则表达式匹配装置,基于正则表达式的指纹对正则表达式进行分组,得到的正则表达式组的数量较少,即正则表达式组编译成的DFA数量较少,能够提高正则表达式的匹配速度,并节省存储空间。
基于同一发明构思,根据本发明上述实施例提供的正则表达式匹配方法,相应地,本发明实施例还提供一种正则表达式匹配装置,其结构示意图如图7所示,具体包括:
第一确定单元701,用于确定正则表达式的指纹;
第二确定单元702,用于根据该正则表达式的指纹,确定该正则表达式的代表指纹;
第三确定单元703,用于根据该正则表达式的代表指纹,确定正则表达式组,并确定该正则表达式组的代表指纹;
匹配单元704,用于基于该正则表达式组的代表指纹与该正则表达式组编译成的确定有限状态自动机DFA的对应关系,对待匹配数据进行正则表达式匹配。
进一步的,第一确定单元701,具体用于提取正则表达式的必经字符串,并截取预设长度的该必经字符串作为该正则表达式的指纹;该必经字符串为能够匹配上该正则表达式的数据中都包含的字符串。
进一步的,第一确定单元701,具体用于当正则表达式中至少包含嵌套元字符时,若最外层嵌套元字符中不包含分支元字符,且最外层嵌套元字符后没有重复元字符,则提取删除该正则表达式的最外层嵌套元字符后的正则表达式的必经字符串,作为该正则表达式的必经字符串;
当正则表达式中至少包含嵌套元字符和分支元字符时,若任何嵌套元字符中均不包含分支元字符,或仅最外层嵌套元字符包含分支元字符,确定该正则表达式包括的不包含分支元字符的分支正则表达式;提取该分支正则表达式的必经字符串;确定该正则表达式的必经字符串为所有分支正则表达式的必经字符串中都包含的字符串;
当正则表达式中至少包含嵌套元字符、分支元字符和重复元字符时,若任何嵌套元字符中均不包含重复元字符,确定该正则表达式包括的不包含分支元字符的分支正则表达式;提取该分支正则表达式的必经字符串;确定该正则表达式的必经字符串为所有分支正则表达式的必经字符串。
进一步的,第二确定单元702,具体用于将该正则表达式的指纹进行哈希,选择哈希冲突最小的指纹作为该正则表达式的代表指纹。
选择哈希冲突最小的指纹作为正则表达式的代表指纹,能够在正则表达式分组时,尽量避免哈希冲突,使代表指纹的哈希值相同的正则表达式尽量合并为一个正则表达式组,因此能够减少正则表达式组的数量,从而减少编译成的DFA的数量,提高正则表达式的匹配速度。
进一步的,第三确定单元703,具体用于根据该正则表达式的代表指纹的哈希值,将该正则表达式放入哈希槽中,并判断放入的哈希槽中是否已存在正则表达式;在放入的哈希槽中已存在正则表达式时,若该正则表达式的代表指纹和已存在正则表达式的代表指纹相同,则将该正则表达式和已存在正则表达式合并为一个正则表达式组。
较佳的,第三确定单元703,还用于将该正则表达式和已存在正则表达式合并为一个正则表达式组之前,判断该正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量是否超过预设阈值;
第三确定单元703,具体用于在该正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量不超过预设阈值时,将该正则表达式和已存在正则表达式合并为一个正则表达式组。
由于正则表达式组编译成的DFA过大时不但会占用较大的存储空间,更会降低后续正则表达式匹配时的匹配速度,因此,采用在该正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量不超过预设阈值时,才将该正则表达式和已存在正则表达式合并为一个正则表达式组的方案,不但能够节省正则表达式组编译成的DFA占用的存储空间,更能够提高正则表达式的匹配速度。
进一步的,第三确定单元703,具体用于将该正则表达式组的指纹进行哈希,选择哈希值在所有正则表达式组的代表指纹的哈希值中出现次数最少的指纹作为该正则表达式组的代表指纹。
选择哈希值在所有正则表达式组的代表指纹的哈希值中出现次数最少的指纹作为该正则表达式组的代表指纹,即可以使各正则表达式组的代表指纹的哈希值尽量不同,使各正则表达式组尽量放入不同的哈希槽中,进行正则表达式的匹配时,能够提高配速度。
上述各单元的功能可对应于图1-图3或图5所示流程中的相应处理步骤,在此不再赘述。
综上所述,采用本发明实施例提供的装置,正则表达式组编译成的DFA的数量较少,可以提高正则表达式匹配速度,节省存储空间。
图8描述了本发明另一个实施例提供的设备,包括至少一个处理器801(例如CPU),存储器802,和至少一个通信总线803,用于设备各部分之间的连接通信。处理器801用于执行存储器802中存储的可执行模块,例如计算机程序。存储器802可能包含高速随机存取存储器(RAM:Random Access Memory),也可能还包括非不稳定的存储器(non-volatile memory),例如至少一个磁盘存储器。通过至少一个处理器访问内存中的地址。
在一些实施方式中,存储器802存储了程序8021,程序8021可以被处理器801执行,这个程序包括:确定正则表达式的指纹;根据该正则表达式的指纹,确定该正则表达式的代表指纹;根据该正则表达式的代表指纹,确定正则表达式组,并确定该正则表达式组的代表指纹;基于该正则表达式组的代表指纹与该正则表达式组编译成的确定有限状态自动机DFA的对应关系,对待匹配数据进行正则表达式匹配。具体的实施步骤与图1所示的实施例相同,此处不再赘述。
可见,基于正则表达式的指纹对正则表达式进行分组,相比于现有技术,可以得到数量较少的正则表达式组,即正则表达式组编译成的DFA的数量较少,可以提高正则表达式匹配速度,并且不会占用大量的存储空间。
在一些实施方式中,程序8021具体包括:提取正则表达式的必经字符串,并截取预设长度的该必经字符串作为该正则表达式的指纹;该必经字符串为能够匹配上该正则表达式的数据中都包含的字符串。
在一些实施方式中,程序8021具体包括:当正则表达式中至少包含嵌套元字符时,若最外层嵌套元字符中不包含分支元字符,且最外层嵌套元字符后没有重复元字符,则提取删除该正则表达式的最外层嵌套元字符后的正则表达式的必经字符串,作为该正则表达式的必经字符串;
当正则表达式中至少包含嵌套元字符和分支元字符时,若任何嵌套元字符中均不包含分支元字符,或仅最外层嵌套元字符包含分支元字符,确定该正则表达式包括的不包含分支元字符的分支正则表达式;提取该分支正则表达式的必经字符串;确定该正则表达式的必经字符串为所有分支正则表达式的必经字符串中都包含的字符串;
当正则表达式中至少包含嵌套元字符、分支元字符和重复元字符时,若任何嵌套元字符中均不包含重复元字符,确定该正则表达式包括的不包含分支元字符的分支正则表达式;提取该分支正则表达式的必经字符串;确定该正则表达式的必经字符串为所有分支正则表达式的必经字符串。
在一些实施方式中,程序8021具体包括:将该正则表达式的指纹进行哈希,选择哈希冲突最小的指纹作为该正则表达式的代表指纹。
选择哈希冲突最小的指纹作为正则表达式的代表指纹,能够在正则表达式分组时,尽量避免哈希冲突,使代表指纹的哈希值相同的正则表达式尽量合并为一个正则表达式组,因此能够减少正则表达式组的数量,从而减少编译成的DFA的数量,提高正则表达式的匹配速度。
在一些实施方式中,程序8021具体包括:根据该正则表达式的代表指纹的哈希值,将该正则表达式放入哈希槽中,并判断放入的哈希槽中是否已存在正则表达式;
在放入的哈希槽中已存在正则表达式时,若该正则表达式的代表指纹和已存在正则表达式的代表指纹相同,则将该正则表达式和已存在正则表达式合并为一个正则表达式组。
在一些实施方式中,程序8021具体还包括:将该正则表达式和已存在正则表达式合并为一个正则表达式组之前,判断该正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量是否超过预设阈值;
程序8021具体包括:在该正则表达式和已存在正则表达式合并为一个正则表达式组后编译成的DFA状态数量不超过预设阈值时,将该正则表达式和已存在正则表达式合并为一个正则表达式组。
采用在正则表达式组编译成的DFA的状态的数量不超过预设阈值时确定正则表达式组的方案,能够避免正则表达式组编译成的DFA过大,从而能够避免正则表达式组编译成的DFA占用较大的存储空间,更能够避免因为DFA过大而导致的正则表达式匹配速度的降低。
在一些实施方式中,程序8021具体包括:将该正则表达式组的指纹进行哈希,选择哈希值在所有正则表达式组的代表指纹的哈希值中出现次数最少的指纹作为该正则表达式组的代表指纹。
选择哈希值在所有正则表达式组的代表指纹的哈希值中出现次数最少的指纹作为该正则表达式组的代表指纹,可以使各正则表达式组的代表指纹的哈希值尽量不同,使各正则表达式组尽量放入不同的哈希槽中,进行正则表达式的匹配时,能够提高配速度。
综上所述,采用本发明实施例提供的设备,正则表达式组编译成的DFA的数量较少,可以提高正则表达式匹配速度,节省存储空间。
本领域内的技术人员应明白,本发明的实施例可提供为方法、系统、或计算机程序产品。因此,本发明可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本发明可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本发明是参照根据本发明实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
尽管已描述了本发明的优选实施例,但本领域内的技术人员一旦得知了基本创造性概念,则可对这些实施例作出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本发明范围的所有变更和修改。
显然,本领域的技术人员可以对本发明实施例进行各种改动和变型而不脱离本发明实施例的精神和范围。这样,倘若本发明实施例的这些修改和变型属于本发明权利要求及其等同技术的范围之内,则本发明也意图包含这些改动和变型在内。