多正则表达式匹配工具 的用法
2014年5月4日09:03从http://code.google.com/p/febird/wiki/MultiRegexMatch更新至最新版 IntroductionThis Multiple Regex Matching solution includes two parts:
介绍这个程序包含一个非常高效的算法,用来匹配多个正则表达式。经过预处理,仅用 O(n) 的时间复杂度,就可以识别出一个输入字符串(长度为n)能匹配哪些(可能是多个)正则表达式。算法的详细内容可参见:
作为一个完整的解决方案,这个程序包括两部分:
Compile$ cd febird-trunk $ make -C tools/regex $ ll tools/regex/*/*.exe -rwxrwxrwx 1 leipeng leipeng 15M 2013-11-02 15:41:54 tools/regex/dbg/regex_build.exe -rwxrwxrwx 1 leipeng leipeng 26M 2013-11-02 15:42:06 tools/regex/rls/regex_build.exe regex_builder 使用方法regex_builder.exe 将很多个正则表达式 offline build成一个DFA文件,online程序使用时,先加载DFA文件,当匹配文本时,可以获知匹配到了哪些正则表达式,同一个文本可能匹配多个正则表达式。 匹配接口分文本接口于二进制接口两种,目前二进制接口已经有了很友好的封装,推荐使用。 文本接口的使用方法与之前的DFA词表完全相同(match_key接口)。 该程序使用 re2 的parser前端,生成 febird 自己的 DFA 文件 命令行选项与参数命令行: regex_build.exe Options
关于 -d 选项一开始 febird DFA 通过 match_key 接口来实现正则表达式匹配,必须在 byte 的取值范围 [0,256) 之间取一个作为分隔符。后来,经过仔细考虑,通过扩充自动机的字符集( r1303),从而 delimeter 可以在 [0,256) 之外取值,于是就不再需要从 [0,256) 取一个特殊值来作为分隔符。 这样,正则表达式匹配就可以有更广的适用范围。另一方面,表面上看,似乎去除一个特殊byte值作为delimeter会影响二进制模式的匹配,其实一点也不会。正则表达式相当于key,正则表达式的 id 相当于是 value,delimeter 不能出现在 key 中,但可以出现在 value 中,从而,value可以是任意二进制数据。实际上,二进制匹配接口的实现是先于 r1303的。 于是,现在,只有在当 你知道你在干什么的时候,才需要指定 -d delim选项,否则,一定不要用 -d 输入文件Regex.txt 的格式regexp t id 第一列是正则表达式,如果行首字符是*,表示忽略该正则表达式的 one pass 属性,无条件获取 submatch,用*做标志的原因是以*开头的正则表达式是非法的正则,从而不会引发歧义,也不会减少表达能力。 第二列是正则表达式的id,该id可以是任意字符串,用来标识这条规则。多个正则表达式可以有相同的id,此时等效于将多个正则表达式或起来放在一行。 一个示例的Regex.txta.*b a-dot-star-b a[a-f]*b 1 a]*([a-c]*)+[bc]+ 2 a(1|234)[ab][ab]{5} 3 a([0-3a-dx-z,})[2cdxy]*abc 4 [358][9])[8} mobile-phone-num +86-(} china-mobiled{}.d} ip_address antidisestablishmentarianism 一般人能看懂的最长单词 非常重要!注意事项!谨慎使用.*,特别是当.*处于正则表达式开头时 普通字符串(不包括正则表达式的元字符)也可以放进Regex.txt,可以为所有普通字符串赋予一个相同的id,这样就将正则表达式和普通字符串build到同一个DFA中了,普通字符串在DFA中占的空间相对要小得多,如果普通字符串很多,可以尝试用 -t x选项,看生成的DFA文件是否更小。 匹配接口: 二进制模式要使用二进制接口,在使用 regex_build.exe 创建自动机时,必须加 -b bin_meta_file 选项 MultiRegexFullMatch参考MultiRegexFullMatch示例程序 MultiRegexSubMatch参考MultiRegexSubmatch示例程序 匹配任意位置如果要匹配任意位置,需要自己每次前进一个(utf8)字符,重新开始匹配(match_and_print):
#include <febird/util/unicode_iterator.hpp> // for febird::utf8_byte_count // ...... // ... fstring text = some string; for (size_t off = 0; off < text.size(); ) { fstring suffix(text.begin() + off,text.end()); match_and_print(sub,suffix); off += febird::utf8_byte_count(text[off]); }
匹配接口: 文本模式文本接口是在创建该算法的原型时使用的,不推荐使用,除非作为 Demo 或者——你知道你在干什么! 匹配接口使用方法可以参考DFA_Interface::match_key 示例程序 直接去 febird-trunk/samples/automata/abstract_api/ 目录运行 make即可编译,编译输出在 rls 和 dbg 目录下 编译出来的 match_key 程序可用来测验匹配(match_key程序使用的 delimiter是 t ): febird-trunk/samples/automata/abstract_api/rls/match_key -d -i samples.dfa abcccb 输出: abcccb ---------- ab value: idx=00000000 str1 ab value00000001 str2 ab value00000002 str=a-b abc value2 abcc value2 abccc value2 abcccb value1 abcccb value-b 输出的 str=1 str=2 str= a-dot-star-b就是匹配到了id为1、2、a-dot-star-b的正则表达式 使用 match_key 接口,正则表达式匹配和词典匹配就完全相同。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |