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