Java 如何使用Lucene分析器标记字符串?

Java 如何使用Lucene分析器标记字符串?,java,lucene,tokenize,analyzer,Java,Lucene,Tokenize,Analyzer,有没有一种简单的方法可以使用Lucene的分析器的任何子类来解析/标记字符串 比如: String to_be_parsed = "car window seven"; Analyzer analyzer = new StandardAnalyzer(...); List<String> tokenized_string = analyzer.analyze(to_be_parsed); 要分析的字符串=“车窗七”; 分析仪=新标准分析仪(…); List tokenized_st

有没有一种简单的方法可以使用Lucene的
分析器的任何子类来解析/标记
字符串

比如:

String to_be_parsed = "car window seven";
Analyzer analyzer = new StandardAnalyzer(...);
List<String> tokenized_string = analyzer.analyze(to_be_parsed);
要分析的字符串=“车窗七”;
分析仪=新标准分析仪(…);
List tokenized_string=analyzer.analyze(待解析);

据我所知,您必须自己编写循环。类似这样的内容(直接取自我的源代码树):

公共最终类lucenutils{
公共静态列表关键字(分析器、字符串字段、字符串关键字){
列表结果=新建ArrayList();
TokenStream=analyzer.TokenStream(字段,新StringReader(关键字));
试一试{
while(stream.incrementToken()){
add(stream.getAttribute(TermAttribute.class).term());
}
}
捕获(IOE异常){
//没有抛出b/c我们正在使用字符串读取器。。。
}
返回结果;
}  
}

根据上述答案,对其进行了轻微修改,以适用于Lucene 4.0

public final class LuceneUtil {

  private LuceneUtil() {}

  public static List<String> tokenizeString(Analyzer analyzer, String string) {
    List<String> result = new ArrayList<String>();
    try {
      TokenStream stream  = analyzer.tokenStream(null, new StringReader(string));
      stream.reset();
      while (stream.incrementToken()) {
        result.add(stream.getAttribute(CharTermAttribute.class).toString());
      }
    } catch (IOException e) {
      // not thrown b/c we're using a string reader...
      throw new RuntimeException(e);
    }
    return result;
  }

}
公共最终类LuceneUtil{ 私有LuceneUtil(){} 公共静态列表标记字符串(Analyzer、字符串){ 列表结果=新建ArrayList(); 试一试{ TokenStream=analyzer.TokenStream(null,新的StringReader(string)); stream.reset(); while(stream.incrementToken()){ add(stream.getAttribute(chartermatAttribute.class).toString()); } }捕获(IOE异常){ //没有抛出b/c我们正在使用字符串读取器。。。 抛出新的运行时异常(e); } 返回结果; } }
使用“与资源一起尝试”会更好!这样,您就不必显式调用库的更高版本所需的
.close()

public static List<String> tokenizeString(Analyzer analyzer, String string) {
  List<String> tokens = new ArrayList<>();
  try (TokenStream tokenStream  = analyzer.tokenStream(null, new StringReader(string))) {
    tokenStream.reset();  // required
    while (tokenStream.incrementToken()) {
      tokens.add(tokenStream.getAttribute(CharTermAttribute.class).toString());
    }
  } catch (IOException e) {
    new RuntimeException(e);  // Shouldn't happen...
  }
  return tokens;
}

如图所示,最新的最佳实践似乎是向令牌流添加属性,然后访问该属性,而不是直接从令牌流获取属性。为了更好的测量,你可以确保分析仪关闭。使用最新的Lucene(当前为v8.6.2),代码如下所示:

String text=“foo-bar”;
字符串fieldName=“myField”;
List tokens=new ArrayList();
尝试(Analyzer=new StandardAnalyzer()){
try(final-TokenStream-TokenStream=analyzer.TokenStream(fieldName,text)){
CharTermAttribute CharTermAttribute=tokenStream.addAttribute(CharTermAttribute.class);
tokenStream.reset();
while(tokenStream.incrementToken()){
add(chartermatAttribute.toString());
}
tokenStream.end();
}
}
代码完成后,
标记
将包含一个已解析标记的列表

另见:


警告:我刚刚开始编写Lucene代码,所以我没有很多Lucene经验。然而,我花了时间研究了最新的文档和相关帖子,我相信我在这里放置的代码遵循了最新的推荐实践,比当前的答案稍微好一些。

你问的问题相当模糊。答案是肯定的。但这在很大程度上取决于您希望如何解析/标记所述字符串。@stevevls添加了一个示例。我使用了List,但它不一定是一个List。再注意一点:从Lucene 3.2开始,TermAttribute被弃用,取而代之的是CharterMatAttribute。在Lucene 4.1中,您还需要在
while
语句之前添加
stream.reset()
,您可能需要添加
stream.end();stream.close()在while坡度之后。注意;以上功能在Lucene 7.0.1中运行良好。只需在
TokenStream
上的
资源中添加糖即可。
public static List<String> tokenizeString(Analyzer analyzer, String string) {
  List<String> tokens = new ArrayList<>();
  try (TokenStream tokenStream  = analyzer.tokenStream(null, new StringReader(string))) {
    tokenStream.reset();  // required
    while (tokenStream.incrementToken()) {
      tokens.add(tokenStream.getAttribute(CharTermAttribute.class).toString());
    }
  } catch (IOException e) {
    new RuntimeException(e);  // Shouldn't happen...
  }
  return tokens;
}
  try (Tokenizer standardTokenizer = new HMMChineseTokenizer()) {
    standardTokenizer.setReader(new StringReader("我说汉语说得很好"));
    standardTokenizer.reset();
    while(standardTokenizer.incrementToken()) {
      standardTokenizer.getAttribute(CharTermAttribute.class).toString());
    }
  } catch (IOException e) {
      new RuntimeException(e);  // Shouldn't happen...
  }