WildcardTermEnum.cs
上传用户:zhangkuixh
上传日期:2013-09-30
资源大小:5473k
文件大小:6k
- /*
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- using System;
- using IndexReader = Lucene.Net.Index.IndexReader;
- using Term = Lucene.Net.Index.Term;
- namespace Lucene.Net.Search
- {
-
- /// <summary> Subclass of FilteredTermEnum for enumerating all terms that match the
- /// specified wildcard filter term.
- /// <p>
- /// Term enumerations are always ordered by Term.compareTo(). Each term in
- /// the enumeration is greater than all that precede it.
- ///
- /// </summary>
- /// <version> $Id: WildcardTermEnum.java 329859 2005-10-31 17:05:36Z bmesser $
- /// </version>
- public class WildcardTermEnum : FilteredTermEnum
- {
- internal Term searchTerm;
- internal System.String field = "";
- internal System.String text = "";
- internal System.String pre = "";
- internal int preLen = 0;
- internal bool endEnum = false;
-
- /// <summary> Creates a new <code>WildcardTermEnum</code>. Passing in a
- /// {@link Lucene.Net.index.Term Term} that does not contain a
- /// <code>WILDCARD_CHAR</code> will cause an exception to be thrown.
- /// <p>
- /// After calling the constructor the enumeration is already pointing to the first
- /// valid term if such a term exists.
- /// </summary>
- public WildcardTermEnum(IndexReader reader, Term term):base()
- {
- searchTerm = term;
- field = searchTerm.Field();
- text = searchTerm.Text();
-
- int sidx = text.IndexOf((System.Char) WILDCARD_STRING);
- int cidx = text.IndexOf((System.Char) WILDCARD_CHAR);
- int idx = sidx;
- if (idx == - 1)
- {
- idx = cidx;
- }
- else if (cidx >= 0)
- {
- idx = System.Math.Min(idx, cidx);
- }
-
- pre = searchTerm.Text().Substring(0, (idx) - (0));
- preLen = pre.Length;
- text = text.Substring(preLen);
- SetEnum(reader.Terms(new Term(searchTerm.Field(), pre)));
- }
-
- protected internal override bool TermCompare(Term term)
- {
- if (field == term.Field())
- {
- System.String searchText = term.Text();
- if (searchText.StartsWith(pre))
- {
- return WildcardEquals(text, 0, searchText, preLen);
- }
- }
- endEnum = true;
- return false;
- }
-
- public override float Difference()
- {
- return 1.0f;
- }
-
- public override bool EndEnum()
- {
- return endEnum;
- }
-
- /// <summary>*****************************************
- /// String equality with support for wildcards
- /// ******************************************
- /// </summary>
-
- public const char WILDCARD_STRING = '*';
- public const char WILDCARD_CHAR = '?';
-
- /// <summary> Determines if a word matches a wildcard pattern.
- /// <small>Work released by Granta Design Ltd after originally being done on
- /// company time.</small>
- /// </summary>
- public static bool WildcardEquals(System.String pattern, int patternIdx, System.String string_Renamed, int stringIdx)
- {
- int p = patternIdx;
-
- for (int s = stringIdx; ; ++p, ++s)
- {
- // End of string yet?
- bool sEnd = (s >= string_Renamed.Length);
- // End of pattern yet?
- bool pEnd = (p >= pattern.Length);
-
- // If we're looking at the end of the string...
- if (sEnd)
- {
- // Assume the only thing left on the pattern is/are wildcards
- bool justWildcardsLeft = true;
-
- // Current wildcard position
- int wildcardSearchPos = p;
- // While we haven't found the end of the pattern,
- // and haven't encountered any non-wildcard characters
- while (wildcardSearchPos < pattern.Length && justWildcardsLeft)
- {
- // Check the character at the current position
- char wildchar = pattern[wildcardSearchPos];
-
- // If it's not a wildcard character, then there is more
- // pattern information after this/these wildcards.
- if (wildchar != WILDCARD_CHAR && wildchar != WILDCARD_STRING)
- {
- justWildcardsLeft = false;
- }
- else
- {
- // to prevent "cat" matches "ca??"
- if (wildchar == WILDCARD_CHAR)
- {
- return false;
- }
-
- // Look at the next character
- wildcardSearchPos++;
- }
- }
-
- // This was a prefix wildcard search, and we've matched, so
- // return true.
- if (justWildcardsLeft)
- {
- return true;
- }
- }
-
- // If we've gone past the end of the string, or the pattern,
- // return false.
- if (sEnd || pEnd)
- {
- break;
- }
-
- // Match a single character, so continue.
- if (pattern[p] == WILDCARD_CHAR)
- {
- continue;
- }
-
- //
- if (pattern[p] == WILDCARD_STRING)
- {
- // Look at the character beyond the '*'.
- ++p;
- // Examine the string, starting at the last character.
- for (int i = string_Renamed.Length; i >= s; --i)
- {
- if (WildcardEquals(pattern, p, string_Renamed, i))
- {
- return true;
- }
- }
- break;
- }
- if (pattern[p] != string_Renamed[s])
- {
- break;
- }
- }
- return false;
- }
-
- public override void Close()
- {
- base.Close();
- searchTerm = null;
- field = null;
- text = null;
- }
- }
- }