Matched fragment when using Lucene's RegexQuery
I'm performing query operations on a Lucene index with a RegexQuery. For example, I do a RegexQuery to obtain all documents containing a URL, using new RegexQuery(new Term("text", "https?://[^\\s]+")
(I know, the RegEx is over-simplified).
Now I want to retrieve the text fr开发者_运维知识库agment, which actually matched my query, like http://example.com
. Does Lucene offer an efficient possibility therefore? Or do I have process the whole text again, using Java's RegEx matcher?
I think that the thing you exactly want is impossible, but here is a different approach that has a similar effect:
Open an Indexreader, get all terms which are after "http" (ordered by lexicographical order1) until they don't start with "http://" or "https://" anymore:
final IndexReader reader = IndexReader.open(IndexHelper.DIRECTORY, true);
final TermEnum termEnum = reader.terms(new Term("text", "http"));
final List<Term> terms = new ArrayList<Term>();
Term foundTerm = termEnum.term();
// if the first term does not match url pattern: advance until it first matches
if (!(foundTerm.text().startsWith("https://") || foundTerm.text().startsWith("http://"))) {
while (termEnum.next()) {
foundTerm = termEnum.term();
if (foundTerm.text().startsWith("https://") || foundTerm.text().startsWith("http://")) {
break;
}
}
}
// collect all terms
while ((foundTerm.text().startsWith("https://") || foundTerm.text().startsWith("http://")) && termEnum.next()) {
foundTerm = termEnum.term();
terms.add(foundTerm);
}
The resulting urls are then in the "terms" list, as lucene Terms.
This of course has the disadvantage that you don't get the documents in which these URLs were found, but you can query them afterwards again with the found terms.
The way I layed it out here is not very flexible (but possibly faster for the task to achieve), but you can of course go back to patterns to achieve more flexibility. Then you would replace all foundTerm.text().startsWith("https://") || foundTerm.text().startsWith("http://")
with yourPattern.matches(foundTerm.text())
.
And sorry that I wrote so much ^^.
I hope it helps.
精彩评论