4

我正在使用 Aho-Corasick 文本匹配,想知道是否可以将其更改为匹配术语而不是字符。换句话说,我希望条款成为匹配的基础,而不是字符。举个例子:

搜索查询:“他”,

句子:“你好世界”,

Aho-Corasick 会将“he”匹配到以索引 2 结尾的句子“hello world”,但我宁愿不匹配。所以,我的意思是“术语”单词而不是字符。

4

4 回答 4

10

一种方法是照常使用 Aho-Corasick,然后执行过滤步骤,消除所有误报。例如,每次找到匹配项时,您可以确认输入中的下一个和前一个字符是非字母字符,如空格或标点符号。这样,您可以获得 Aho-Corasick 查找的速度,但只考虑在文本中显示为整个单词的匹配项。

希望这可以帮助!

于 2013-01-21T19:13:46.547 回答
6

一种可能性是在您的搜索词中包含空格字符,可能在预处理您的输入以将各种空格(空格、换行、回车、制表符...)转换为相同的空格字符之后。

另一种可能性是将你的字母表中的字符,就 Aho-Corasick 而言,是单词。Aho-Corasick 将与大小为 2^32 的字母表一样快(如果不是更快),其中输入文本中看到的每个单词都被编码为单个字符,就像它与大小为 2^8 的字母表一样,其中一个像往常一样,字符只是一个字节。

无论哪种情况,您都必须决定预处理对标点符号的作用。

于 2013-01-21T20:05:22.783 回答
1

如果您使用 onlyWholewords() 方法,则上面的示例应该没有结果。例如:

Trie trie = Trie.builder()
             .onlyWholeWords()
             .addKeyword("He")
             .build();
Collection<Emit> emits = trie.parseText("Hello World");

在这种情况下发出将是空的。

它只会导致整个单词只有“他”。

虽然要注意不是 [az AZ] 的字符。例如,如果您:

"He//Is" 

它会拿起“He”并忽略“//”

补充两点:

  1. 如果要断言单词边界,可以使用:

    onlyWholeWordsWhiteSpaceSeparated() 而不是

    只有WholeWords()

  2. 如果您想将某些字符“列入白名单”,此阅读可能会有所帮助:

使用的单词字符是由提供的字符修改的默认字符,布尔标志表示字符打开和关闭的位置。当您只想关闭默认字符集中的特定字符时,这很有用。例如:

使用的单词字符是由提供的字符修改的默认字符,布尔标志表示字符打开和关闭的位置。当您只想关闭默认字符集中的特定字符时,这很有用。例如:

新 WholeWordMatchSet(关键字,真,['_','='],[假,真])

将生成一个集合,其中字母和数字以及 - 和 = 被视为单词字符,而不是 _。

于 2020-10-11T22:47:35.673 回答
0

聚会很晚,但另一种选择是在 trie 中插入一些表示单词开头和结尾的符号。然后,在匹配阶段,它们必须相应地匹配。我将自己尝试这种方法。

于 2019-10-28T00:40:55.053 回答