我有一个模式列表,这些模式的体内任何位置都包含零个或多个通配符(*
):
bleurgh
p0*
p*w
p*w*
*01
*.nowsich.* (dots here are meaningless)
仅允许使用通配符(这不是任何形式的完整正则表达式),并且它们可以出现在模式中的任何位置。不允许使用仅使用通配符的模式,并且双通配符(**
)是荒谬的,因为它与*
相同(但可以保证有人会尝试。)大约有100,000个一百万。
代码将看到可能匹配的新目标字符串:
p01w01
pod01whiskey02
ppp.nowsich.com
aZL8u4qXfg!LooksLikeRandomGarbageToMe!kx961giRVV
callmeishmael
这些字符串是无界的,但可能少于32个字符,并且代码将以每秒两次的顺序看到它们(这是一种低速率的东西。)
我正在寻找一种方法来反向查找字符串可能匹配的模式:(这里是输入到输出)
m01z01 -> *01
p03w01 -> p0*, p*w*, *01
bleurgh -> bleurgh
www.nowsich.org -> *.nowsich.*
wut -> [the empty list]
我没有受到记忆的束缚;更快的查找肯定更好。
到目前为止,我能想到的最好的办法是建立模式组件的有向图,其中每个组件都是split("*", pattern)
的输出,尾随的通配符绑定到它们的叶子:
___ {implied root node}
/ / | \
[bleurgh] [p0] [p] [] // leading wildcard?
/ / / \
[w] [w*] [01] [.nowsich.*]
...并在树上执行DFS,选择那些根节点正则表达式与从子树的父节点重新编译的模式(一直到根)相匹配的子树。我不喜欢这样的想法, O(log n)
?正则表达式,但数据集并不庞大。另外,我相信我必须始终搜索树的“前导通配符”分支,因此也许可以搜索一对这样的树(有无前导通配符的一棵树)。
有些先前的艺术似乎由于各种原因而没有应用:
Good algorithm and data structure for looking up words with missing letters?
Efficient string matching algorithm
这两个都有其自己的约束,这些约束与我的不相称。
问题是:a)我上面概述的方法是否有意义;和b)您有更好的方法吗?
答案 0 :(得分:0)
完成了一些实际的写作,这就是我学到的东西:
*
-char具有特殊含义。)如果没有前导或尾随通配符,则需要在模式的第一个或最后一个键上包含锚点。这意味着模式*p0*
和p0*
由树中的两个节点表示。 (对于叶节点类似-即模式中的最终令牌。).
,[
,]
,{{1 }},{
等。可以将它们包括在模式匹配树中,但您必须以不同的方式标记化标记。}
的结果。