Ja, es ist ein wenig verworren (im Vergleich zum guten alten Weg), aber das sollte es tun:
TokenStream tokenStream = analyzer.tokenStream(fieldName, reader);
OffsetAttribute offsetAttribute = tokenStream.getAttribute(OffsetAttribute.class);
TermAttribute termAttribute = tokenStream.getAttribute(TermAttribute.class);
while (tokenStream.incrementToken()) {
int startOffset = offsetAttribute.startOffset();
int endOffset = offsetAttribute.endOffset();
String term = termAttribute.term();
}
Edit: Der neue Weg
Laut Donotello wurde TermAttribute
zugunsten von abgelehnt CharTermAttribute
. Laut jpountz (und Lucenes Dokumentation) addAttribute
ist dies wünschenswerter als getAttribute
.
TokenStream tokenStream = analyzer.tokenStream(fieldName, reader);
OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
tokenStream.reset();
while (tokenStream.incrementToken()) {
int startOffset = offsetAttribute.startOffset();
int endOffset = offsetAttribute.endOffset();
String term = charTermAttribute.toString();
}
CharTermAttributeImpl.toString()
stattdessen so etwas wie verwendenreset()
mit Lucene 4.3 anrufen , nahm sich also die Freiheit, es hinzuzufügenSo sollte es sein (eine saubere Version von Adams Antwort):
TokenStream stream = analyzer.tokenStream(null, new StringReader(text)); CharTermAttribute cattr = stream.addAttribute(CharTermAttribute.class); stream.reset(); while (stream.incrementToken()) { System.out.println(cattr.toString()); } stream.end(); stream.close();
quelle
reset()
Für die neueste Version von Lucene 7.3.1
// Test the tokenizer Analyzer testAnalyzer = new CJKAnalyzer(); String testText = "Test Tokenizer"; TokenStream ts = testAnalyzer.tokenStream("context", new StringReader(testText)); OffsetAttribute offsetAtt = ts.addAttribute(OffsetAttribute.class); try { ts.reset(); // Resets this stream to the beginning. (Required) while (ts.incrementToken()) { // Use AttributeSource.reflectAsString(boolean) // for token stream debugging. System.out.println("token: " + ts.reflectAsString(true)); System.out.println("token start offset: " + offsetAtt.startOffset()); System.out.println(" token end offset: " + offsetAtt.endOffset()); } ts.end(); // Perform end-of-stream operations, e.g. set the final offset. } finally { ts.close(); // Release resources associated with this stream. }
Referenz: https://lucene.apache.org/core/7_3_1/core/org/apache/lucene/analysis/package-summary.html
quelle
Es gibt zwei Variationen in der OP-Frage:
Aktuelle Versionen der Lucene-Dokumentation zum Beispiel
Token
(Hervorhebung hinzugefügt):Und
TokenStream
sagt seine API:Die anderen Antworten auf diese Frage beziehen sich auf # 2 oben: Wie man tokenartige Informationen von einem
TokenStream
auf die "neue" empfohlene Weise unter Verwendung von Attributen erhält . Beim Lesen der Dokumentation schlagen die Lucene-Entwickler vor, dass diese Änderung teilweise vorgenommen wurde, um die Anzahl der gleichzeitig erstellten Einzelobjekte zu verringern.Aber wie einige Leute in den Kommentaren dieser Antworten betont haben, antworten sie nicht direkt auf Nummer 1: Wie bekommt man eine,
Token
wenn man diesen Typ wirklich will / braucht?Mit der gleichen API-Änderung, die
TokenStream
einAttributeSource
,Token
jetzt implementiertAttribute
und mit TokenStream.addAttribute verwendet werden kann, genau wie die anderen Antworten fürCharTermAttribute
undOffsetAttribute
. Also haben sie diesen Teil der ursprünglichen Frage wirklich beantwortet, sie haben ihn einfach nicht gezeigt.Es ist wichtig, dass Sie mit diesem Ansatz zwar
Token
während der Schleife zugreifen können , es sich jedoch immer noch um ein einzelnes Objekt handelt, unabhängig davon, wie viele logische Token sich im Stream befinden. Jeder Aufruf vonincrementToken()
ändert den Status desToken
zurückgegebenen vonaddAttribute
; Wenn Sie also eine Sammlung verschiedenerToken
Objekte erstellen möchten, die außerhalb der Schleife verwendet werden sollen, müssen Sie zusätzliche Arbeit leisten, um ein neuesToken
Objekt als (tiefe?) Kopie zu erstellen .quelle