对于Lucene,我想只使用tokenFilter对tokenStream的最后一个标记进行一些处理。例如,给出句子"你好我的世界",只将我的处理应用于" world"而不是其他令牌。
我可以通过首先迭代tokenStream的整个输入来获取最后一个标记的偏移量,然后从第一个标记重新开始。因为我已经知道最后一个令牌的偏移量,所以我可以识别当前令牌是否是最后一个令牌。
然而,由于循环两次肯定是低效的,我只想迭代tokenStream一次,但似乎很难找到正确的方法。
例如,假设MyFilter看起来像:(当然,这个MyFilter是TokenFilter的基本结构)。
public class MyFilter extends TokenFilter{
public MyFilter(TokenStream input){
super(input);
}
@Override
public boolean incrementToken() throws IOException {
if (input.incrementToken()){
/*
if(current token is the last token):
Want to apply something only to the last token.
*/
return true;
}
return false;
}
}
如何识别当前令牌是否是最后一个?
答案 0 :(得分:0)
我可能在这里得到了错误的结论,但我认为 stream 的想法恰恰是你可能能够分辨到它的位置开始但是知道它结束的地方要复杂得多......这可能就是他们称之为Token*Stream*
的原因。
TokenFilter
可以告诉您流何时开始:您只需要覆盖reset()
。
当然,有一种方法TokenFilter.end()
,您可以尝试覆盖它,但Javadoc说:
消费者在最后一个令牌之后调用此方法 在TokenStream.incrementToken()返回false之后消耗(使用 新的TokenStream API)。
...这可能意味着它的输出已经被“消费者”使用了。
为了检测结束,我认为您必须重新设计Tokenizer
。例如,仅查看StandardTokenizer
及其“业务结束”StandardTokenizerImpl
,这可能非常复杂。毫无疑问,最好自己制作简单的Tokeniser
:它接受Strings
或其他任何东西,继续进行的方法是在将标记喷出到过滤器之前进行标记。你会知道将会喷出多少令牌,并且(例如)你在任何时候都可以将这个号码提供给TokenFilter
......