Lucene:如何在标记流时保留空格等?

Lucene:如何在标记流时保留空格等?,lucene,tokenize,stop-words,Lucene,Tokenize,Stop Words,我试图对一系列文本进行“翻译”。更具体地说,我需要标记输入流,在专门的字典中查找每个术语,并输出相应的标记“翻译”。但是,我还希望保留输入中的所有原始空格、stopwords等,以便输出的格式与输入的格式相同,而不是最终成为翻译流。所以如果我的输入是 Term1:Term2停止词!第三学期 第4条 然后我希望输出看起来像 Term1':Term2'停止字!第3条' 术语4' (其中Termi'是Termi的翻译)而不是简单的 Term1'Term2'Term3'Term4' 目前我正在做以下工作

我试图对一系列文本进行“翻译”。更具体地说,我需要标记输入流,在专门的字典中查找每个术语,并输出相应的标记“翻译”。但是,我还希望保留输入中的所有原始空格、stopwords等,以便输出的格式与输入的格式相同,而不是最终成为翻译流。所以如果我的输入是

Term1:Term2停止词!第三学期 第4条

然后我希望输出看起来像

Term1':Term2'停止字!第3条' 术语4'

(其中Termi'Termi的翻译)而不是简单的

Term1'Term2'Term3'Term4'

目前我正在做以下工作:

PatternAnalyzer pa = new PatternAnalyzer(Version.LUCENE_31,
                             PatternAnalyzer.WHITESPACE_PATTERN,
                             false, 
                             WordlistLoader.getWordSet(new File(stopWordFilePath)));
TokenStream ts = pa.tokenStream(null, in);
CharTermAttribute charTermAttribute = ts.getAttribute(CharTermAttribute.class);

while (ts.incrementToken()) { // loop over tokens
     String termIn = charTermAttribute.toString(); 
     ...
}
但是,这当然会丢失所有的空格等。我如何修改它以便能够将它们重新插入到输出中?多谢

=============更新

我尝试将原始流拆分为“单词”和“非单词”。它似乎工作得很好。但不确定这是否是最有效的方法:

public ArrayList splitToWords(字符串sIn)
{

if(sIn==null | | sIn.length()==0){
返回null;
}
char[]c=sIn.toCharArray();
ArrayList=新建ArrayList();
int-tokenStart=0;
布尔curIsLetter=Character.isLetter(c[tokenStart]);
对于(int pos=tokenStart+1;pos
}

它并没有真正丢失空白,您仍然保留了原始文本:)

因此,我认为您应该使用OffsetAttribute,它在原始文本中包含每个术语的startOffset()和endOffset()。例如,这就是lucene用来突出显示原始文本中的搜索结果片段的地方

我写了一个快速测试(使用EnglishAnalyzer)来演示: 输入为:

Just a test of some ideas. Let's see if it works.
输出为:

just a test of some idea. let see if it work.

// just for example purposes, not necessarily the most performant.
public void testString() throws Exception {
  String input = "Just a test of some ideas. Let's see if it works.";
  EnglishAnalyzer analyzer = new EnglishAnalyzer(Version.LUCENE_35);
  StringBuilder output = new StringBuilder(input);
  // in some cases, the analyzer will make terms longer or shorter.
  // because of this we must track how much we have adjusted the text so far
  // so that the offsets returned will still work for us via replace()
  int delta = 0;

  TokenStream ts = analyzer.tokenStream("bogus", new StringReader(input));
  CharTermAttribute termAtt = ts.addAttribute(CharTermAttribute.class);
  OffsetAttribute offsetAtt = ts.addAttribute(OffsetAttribute.class);
  ts.reset();
  while (ts.incrementToken()) {
    String term = termAtt.toString();
    int start = offsetAtt.startOffset();
    int end = offsetAtt.endOffset();
    output.replace(delta + start, delta + end, term);
    delta += (term.length() - (end - start));
  }
  ts.close();

System.out.println(output.toString());

}

你翻译了一段文字,但这与Lucene有什么关系@米兰:实际的翻译是通过对LuceneI索引的字典进行搜索来完成的,LuceneI制作了一个任何标记器的包装,该标记器生成一个带有“缺失标记”的标记流。这是一个更大的项目的一部分,还没有开源,所以如果你想要的话,请给我一个bug。
just a test of some idea. let see if it work.

// just for example purposes, not necessarily the most performant.
public void testString() throws Exception {
  String input = "Just a test of some ideas. Let's see if it works.";
  EnglishAnalyzer analyzer = new EnglishAnalyzer(Version.LUCENE_35);
  StringBuilder output = new StringBuilder(input);
  // in some cases, the analyzer will make terms longer or shorter.
  // because of this we must track how much we have adjusted the text so far
  // so that the offsets returned will still work for us via replace()
  int delta = 0;

  TokenStream ts = analyzer.tokenStream("bogus", new StringReader(input));
  CharTermAttribute termAtt = ts.addAttribute(CharTermAttribute.class);
  OffsetAttribute offsetAtt = ts.addAttribute(OffsetAttribute.class);
  ts.reset();
  while (ts.incrementToken()) {
    String term = termAtt.toString();
    int start = offsetAtt.startOffset();
    int end = offsetAtt.endOffset();
    output.replace(delta + start, delta + end, term);
    delta += (term.length() - (end - start));
  }
  ts.close();

System.out.println(output.toString());