如何使用Lucene Analyzer来标记字符串?

时间:2011-06-13 18:38:15

标签: java lucene tokenize analyzer

有没有一种简单的方法可以使用Lucene Analyzer的任何子类来解析/标记String

类似的东西:

String to_be_parsed = "car window seven";
Analyzer analyzer = new StandardAnalyzer(...);
List<String> tokenized_string = analyzer.analyze(to_be_parsed);

4 个答案:

答案 0 :(得分:56)

根据上面的答案,稍加修改后可以使用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;
  }

}

答案 1 :(得分:38)

据我所知,你必须自己编写循环。这样的东西(直接来自我的源代码树):

public final class LuceneUtils {

    public static List<String> parseKeywords(Analyzer analyzer, String field, String keywords) {

        List<String> result = new ArrayList<String>();
        TokenStream stream  = analyzer.tokenStream(field, new StringReader(keywords));

        try {
            while(stream.incrementToken()) {
                result.add(stream.getAttribute(TermAttribute.class).term());
            }
        }
        catch(IOException e) {
            // not thrown b/c we're using a string reader...
        }

        return result;
    }  
}

答案 2 :(得分:0)

使用try-with-resources会更好!这样,您就不必显式调用库的更高版本中所需的.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;
}

以及Tokenizer版本:

  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...
  }

答案 3 :(得分:0)

another Stack Overflow answer所示,最新的最佳实践似乎是向令牌流添加属性,然后再访问该属性,而不是直接从令牌流中获取属性。采取良好措施,可以确保分析仪已关闭。使用最新的Lucene(当前为v8.6.2),代码如下所示:

String text = "foo bar";
String fieldName = "myField";
List<String> tokens = new ArrayList();
try (Analyzer analyzer = new StandardAnalyzer()) {
  try (final TokenStream tokenStream = analyzer.tokenStream(fieldName, text)) {
    CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
    tokenStream.reset();
    while(tokenStream.incrementToken()) {
      tokens.add(charTermAttribute.toString());
    }
    tokenStream.end();
  }
}

该代码完成后,tokens将包含已解析令牌的列表。

另请参阅:Lucene Analysis Overview

注意事项:我才刚刚开始编写Lucene代码,所以我没有很多Lucene经验。我花了一些时间研究最新的文档和相关文章,但是我相信我在这里放置的代码遵循最新推荐的做法要比当前答案要好一些。