Index: src/java/org/apache/lucene/queryParser/QueryParser.java =================================================================== --- src/java/org/apache/lucene/queryParser/QueryParser.java (revision 604885) +++ src/java/org/apache/lucene/queryParser/QueryParser.java (working copy) @@ -100,7 +100,7 @@ boolean lowercaseExpandedTerms = true; boolean useOldRangeQuery= false; boolean allowLeadingWildcard = false; - + boolean useOldWildcardQuery=true; Analyzer analyzer; String field; int phraseSlop = 0; @@ -299,8 +299,16 @@ return useOldRangeQuery; } + + public boolean getUseOldWildcardQuery() { + return useOldWildcardQuery; + } - /** + public void setUseOldWildcardQuery(boolean useOldWildcardQuery) { + this.useOldWildcardQuery = useOldWildcardQuery; + } + + /** * Set locale used by date range parsing. */ public void setLocale(Locale locale) { @@ -1076,9 +1084,9 @@ jj_la1[11] = jj_gen; ; } - String termImage=discardEscapeChar(term.image); + String termImage=discardEscapeChar(term.image); if (wildcard) { - q = getWildcardQuery(field, termImage); + q= useOldWildcardQuery?getWildcardQuery(field, termImage):getWildcardQuery(field, term.image); } else if (prefix) { q = getPrefixQuery(field, discardEscapeChar(term.image.substring Index: src/java/org/apache/lucene/search/WildcardQuery.java =================================================================== --- src/java/org/apache/lucene/search/WildcardQuery.java (revision 604885) +++ src/java/org/apache/lucene/search/WildcardQuery.java (working copy) @@ -17,9 +17,11 @@ * limitations under the License. */ +import java.io.IOException; + import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; -import java.io.IOException; +import org.apache.lucene.util.ToStringUtils; /** Implements the wildcard search query. Supported wildcards are *, which * matches any character sequence (including the empty one), and ?, @@ -32,10 +34,22 @@ */ public class WildcardQuery extends MultiTermQuery { private boolean termContainsWildcard; - + + private boolean containsWildcard(String text){ + boolean lastEscaped = false; + for(int i=0;iWildcardTermEnum. Passing in a * {@link org.apache.lucene.index.Term Term} that does not contain a @@ -53,8 +99,9 @@ field = searchTerm.field(); text = searchTerm.text(); - int sidx = text.indexOf(WILDCARD_STRING); - int cidx = text.indexOf(WILDCARD_CHAR); + int sidx = indexOf(text,WILDCARD_STRING); + int cidx = indexOf(text,WILDCARD_CHAR); + int idx = sidx; if (idx == -1) { idx = cidx; @@ -63,9 +110,9 @@ idx = Math.min(idx, cidx); } - pre = searchTerm.text().substring(0,idx); + pre = discardEscape( searchTerm.text().substring(0,idx)); preLen = pre.length(); - text = text.substring(preLen); + text = text.substring(idx); setEnum(reader.terms(new Term(searchTerm.field(), pre))); } @@ -105,6 +152,9 @@ { int p = patternIdx; + boolean hitEscaped = false; + + for (int s = stringIdx; ; ++p, ++s) { // End of string yet? @@ -159,7 +209,27 @@ { break; } - + + if(pattern.charAt(p)== '\\'){//we meet '\', but we do not know it is ecsaped or not. + if(!hitEscaped){ + hitEscaped = true; + s--; + continue; + }else{ + if(string.charAt(s)=='\\'){ + hitEscaped = false; + continue; + } + return false; + } + } + if(hitEscaped){ + if(string.charAt(s)!=pattern.charAt(p)){ + return false; + } + continue; + } + // Match a single character, so continue. if (pattern.charAt(p) == WILDCARD_CHAR) { Index: src/test/org/apache/lucene/search/TestWildcard.java =================================================================== --- src/test/org/apache/lucene/search/TestWildcard.java (revision 604885) +++ src/test/org/apache/lucene/search/TestWildcard.java (working copy) @@ -17,20 +17,20 @@ * limitations under the License. */ -import org.apache.lucene.util.LuceneTestCase; +import java.io.IOException; + import org.apache.lucene.analysis.SimpleAnalyzer; import org.apache.lucene.analysis.WhitespaceAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.Field.Index; import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.Field.Index; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.LuceneTestCase; -import java.io.IOException; - /** * TestWildcard tests the '*' and '?' wildcard characters. * @@ -172,7 +172,7 @@ String docs[] = { "\\ abcdefg1", "\\79 hijklmn1", - "\\\\ opqrstu1", + "\\\\ opqrstu1" }; // queries that should find all docs String matchAll[] = { @@ -254,4 +254,51 @@ searcher.close(); } + public void testDocsWithWildcard() throws Exception { + boolean dbg = false; + String docs[] = { + "ab*cdefg", + "abc?defg", + "abcde*fg", + "bc\\?abc" + }; + String query[]= { + "a\\??cdefg",//match 0 docs; + "a\\*?cdefg",//match 0 docs; + "a?c*\\*",//match 0 docs; + "bc\\\\\\?abc",//match 1 docs + "b?\\\\\\?abc",//match 1 docs + "b?*\\?abc",//match 1 docs + "b?*abc",//match 1 docs + }; + int num[]={ + 0, + 0, + 0, + 1, + 1, + 1, + 1 + }; + // prepare the index + RAMDirectory dir = new RAMDirectory(); + IndexWriter iw = new IndexWriter(dir, new WhitespaceAnalyzer()); + for (int i = 0; i < docs.length; i++) { + Document doc = new Document(); + doc.add(new Field("field",docs[i],Store.NO,Index.TOKENIZED)); + iw.addDocument(doc); + } + iw.close(); + + IndexSearcher searcher = new IndexSearcher(dir); + QueryParser qp = new QueryParser("field", new WhitespaceAnalyzer()); + qp.setUseOldWildcardQuery(false); + for (int i = 0; i < query.length; i++) { + String qtxt = query[i]; + Query q = qp.parse(qtxt); + if (dbg) System.out.println("matchAll: qtxt="+qtxt+" q="+q+" "+q.getClass().getName()); + Hits hits = searcher.search(q); + assertEquals(num[i],hits.length()); + } + } }