我希望能够有效地匹配GB中的数千个正则表达式,因为大多数这些正则表达式都非常简单,例如:
\bBarack\s(Hussein\s)?Obama\b \b(John|J\.)\sBoehner\b
等
我目前的想法是尝试从每个正则表达式中提取某种最长的子字符串,然后使用Aho-Corasick匹配这些子字符串并消除大部分正则表达式,然后匹配所有剩余的正则表达式组合。谁能想到更好的东西?
答案 0 :(得分:2)
您可以使用(f)lex生成DFA,它可以识别所有文字并行。如果存在太多通配符,这可能会变得棘手,但它适用于大约100个文字(对于4个字母的alfabet;对于自然文本可能更多)。您可能希望禁止默认操作(ECHO),并仅打印匹配的行+列号。
[我认为grep -F大致相同]
%{
/* C code to be copied verbatim */
#include <stdio.h>
%}
%%
"TTGATTCACCAGCGCGTATTGTC" { printf("@%d: %d:%s\n", yylineno, yycolumn, "OMG! the TTGA pattern again" ); }
"AGGTATCTGCTTCAATCAGCG" { printf("@%d: %d:%s\n", yylineno, yycolumn, "WTF?!" ); }
...
more lines
...
[bd-fh-su-z]+ {;}
[ \t\r\n]+ {;}
. {;}
%%
int main(void)
{
/* Call the lexer, then quit. */
yylex();
return 0;
}
可以使用awk或任何其他脚本语言生成类似于上述脚本的脚本。
答案 1 :(得分:0)
比在每个文件上运行每个正则表达式更简单的实现:
For each regex:
load regex into a regex engine
assemble a list of regex engines
For each byte in the file:
insert byte to every regex engine
print results if there are matches
但我不知道有任何程序已经执行此操作 - 您必须自己编写代码。这也意味着你有ram来保持正则表达式状态,并且你没有任何邪恶的正则表达式
答案 2 :(得分:0)
我不确定你是否会破坏一些正则表达式的大小限制,但你可以将它们全部组合成一个巨大的正则表达式:
((\bBarack\s(Hussein\s)?Obama\b)|(\b(John|J\.)\sBoehner\b)|(etc)|(etc))
如果达到某个限制,您可以一次使用100个块,或者可以管理多少
答案 3 :(得分:0)
如果您需要快速实施某些特定案例,您可以自己实施suffix tree Aho–Corasick algorithm。但在大多数情况下,如前所述,将所有正则表达式组合成单个正则表达式也不错 -