我正在解决一个问题,即我有短信与数以千计的表格
的正则表达式相匹配<some string> {0 or 300 chars} <some string> {0 or 300 chars}
e.g。
"on"[ \t\r]*(.){0,300}"."[ \t\r]*(.){0,300}"from"
或者一个真实的例子可以是
"Dear"[ \t\r]*"Customer,"[ \t\r]*"Your"[ \t\r]*"package"[ \t\r]*(.){0,80}[ \t\r]*"is"[ \t\r]*"out"[ \t\r]*"for"[ \t\r]*"delivery"[ \t\r]*"via"(.){0,80}[ \t\r]*"Courier,"[ \t\r]*(.){0,80}[ \t\r]*"on"(.){0,80}"."[ \t\r]*"Delivery"[ \t\r]*"will"[ \t\r]*"be"[ \t\r]*"attempted"[ \t\r]*"in"[ \t\r]*"5"[ \t\r]*"wkg"[ \t\r]*"days."
首先,我使用了Java的正则表达式引擎。我一次将输入字符串与一个正则表达式匹配。这个过程太慢了。我发现Java的正则表达式引擎将正则表达式编译成NFA(非确定性有限自动机),由于灾难性的回溯,它可能会变慢。因此我想到使用flex-lexer将正则表达式转换为DFA(确定性有限自动机),以便将数百个正则表达式编译成一个DFA,因此我将得到O(n)中的匹配结果,n是输入字符串的长度。但是由于正则表达式中固定的重复计数,flex正在永远编译see here。
可能我做错了。有没有更好的方法来做到这一点?我能想到的一种方法是将固定重复次数转换为无限重复(星型算子),如下所示
"on"[ \t\r]*(.)*"."[ \t\r]*(.)*"from"
这个正则表达式编译没有问题,只需几毫秒。如果输入字符串与此规则匹配,我知道输入字符串中存在来自规则("on", "." and "from")
的常量字符串。现在iff flex支持正则表达式的命名组,我可以简单地计算这些组中的字符数并验证但是flex不适用于此目的。
问题 - 有没有办法有效地解决这个问题?