1

ある種のテキストストリームの「翻訳」を実行しようとしています。具体的には、入力ストリームをトークン化し、専門辞書ですべての用語を検索し、トークンの対応する「翻訳」を出力する必要があります。ただし、出力が翻訳のストリームになるのではなく、入力と同じ方法でフォーマットされるように、入力からすべての元の空白、ストップワードなども保持したいと思います。だから私の入力が

Term1:Term2ストップワード!Term3 Term4

次に、出力を次のように表示します

Term1':Term2'ストップワード!Term3'Term4'

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(String sIn) {

if (sIn == null || sIn.length() == 0) {
    return null;
}

char[] c = sIn.toCharArray();
ArrayList<Token> list = new ArrayList<Token>(); 
int tokenStart = 0;
boolean curIsLetter = Character.isLetter(c[tokenStart]);
for (int pos = tokenStart + 1; pos < c.length; pos++) {
    boolean newIsLetter = Character.isLetter(c[pos]);
    if (newIsLetter == curIsLetter) {
        continue;
    }
    TokenType type = TokenType.NONWORD;
    if (curIsLetter == true)
    {
        type = TokenType.WORD;
    }

    list.add(new Token(new String(c, tokenStart, pos - tokenStart),type));
    tokenStart = pos;

    curIsLetter = newIsLetter;
}
TokenType type = TokenType.NONWORD;
if (curIsLetter == true)
{
    type = TokenType.WORD;
}
list.add(new Token(new String(c, tokenStart, c.length - tokenStart),type));

return list;

}

4

1 に答える 1

0

まあ、それは本当に空白を失うことはありません、あなたはまだあなたの元のテキストを持っています:)

したがって、各用語のstartOffset()とendOffset()を元のテキストに含めるOffsetAttributeを使用する必要があると思います。これは、たとえば、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());

}

于 2012-01-14T20:36:44.160 に答える