WildcardTermEnum.cs
上传用户:zhangkuixh
上传日期:2013-09-30
资源大小:5473k
文件大小:6k
源码类别:

搜索引擎

开发平台:

C#

  1. /*
  2.  * Copyright 2004 The Apache Software Foundation
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  * 
  8.  * http://www.apache.org/licenses/LICENSE-2.0
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. using System;
  17. using IndexReader = Lucene.Net.Index.IndexReader;
  18. using Term = Lucene.Net.Index.Term;
  19. namespace Lucene.Net.Search
  20. {
  21. /// <summary> Subclass of FilteredTermEnum for enumerating all terms that match the
  22. /// specified wildcard filter term.
  23. /// <p>
  24. /// Term enumerations are always ordered by Term.compareTo().  Each term in
  25. /// the enumeration is greater than all that precede it.
  26. /// 
  27. /// </summary>
  28. /// <version>  $Id: WildcardTermEnum.java 329859 2005-10-31 17:05:36Z bmesser $
  29. /// </version>
  30. public class WildcardTermEnum : FilteredTermEnum
  31. {
  32. internal Term searchTerm;
  33. internal System.String field = "";
  34. internal System.String text = "";
  35. internal System.String pre = "";
  36. internal int preLen = 0;
  37. internal bool endEnum = false;
  38. /// <summary> Creates a new <code>WildcardTermEnum</code>.  Passing in a
  39. /// {@link Lucene.Net.index.Term Term} that does not contain a
  40. /// <code>WILDCARD_CHAR</code> will cause an exception to be thrown.
  41. /// <p>
  42. /// After calling the constructor the enumeration is already pointing to the first 
  43. /// valid term if such a term exists.
  44. /// </summary>
  45. public WildcardTermEnum(IndexReader reader, Term term):base()
  46. {
  47. searchTerm = term;
  48. field = searchTerm.Field();
  49. text = searchTerm.Text();
  50. int sidx = text.IndexOf((System.Char) WILDCARD_STRING);
  51. int cidx = text.IndexOf((System.Char) WILDCARD_CHAR);
  52. int idx = sidx;
  53. if (idx == - 1)
  54. {
  55. idx = cidx;
  56. }
  57. else if (cidx >= 0)
  58. {
  59. idx = System.Math.Min(idx, cidx);
  60. }
  61. pre = searchTerm.Text().Substring(0, (idx) - (0));
  62. preLen = pre.Length;
  63. text = text.Substring(preLen);
  64. SetEnum(reader.Terms(new Term(searchTerm.Field(), pre)));
  65. }
  66. protected internal override bool TermCompare(Term term)
  67. {
  68. if (field == term.Field())
  69. {
  70. System.String searchText = term.Text();
  71. if (searchText.StartsWith(pre))
  72. {
  73. return WildcardEquals(text, 0, searchText, preLen);
  74. }
  75. }
  76. endEnum = true;
  77. return false;
  78. }
  79. public override float Difference()
  80. {
  81. return 1.0f;
  82. }
  83. public override bool EndEnum()
  84. {
  85. return endEnum;
  86. }
  87. /// <summary>*****************************************
  88. /// String equality with support for wildcards
  89. /// ******************************************
  90. /// </summary>
  91. public const char WILDCARD_STRING = '*';
  92. public const char WILDCARD_CHAR = '?';
  93. /// <summary> Determines if a word matches a wildcard pattern.
  94. /// <small>Work released by Granta Design Ltd after originally being done on
  95. /// company time.</small>
  96. /// </summary>
  97. public static bool WildcardEquals(System.String pattern, int patternIdx, System.String string_Renamed, int stringIdx)
  98. {
  99. int p = patternIdx;
  100. for (int s = stringIdx; ; ++p, ++s)
  101. {
  102. // End of string yet?
  103. bool sEnd = (s >= string_Renamed.Length);
  104. // End of pattern yet?
  105. bool pEnd = (p >= pattern.Length);
  106. // If we're looking at the end of the string...
  107. if (sEnd)
  108. {
  109. // Assume the only thing left on the pattern is/are wildcards
  110. bool justWildcardsLeft = true;
  111. // Current wildcard position
  112. int wildcardSearchPos = p;
  113. // While we haven't found the end of the pattern,
  114. // and haven't encountered any non-wildcard characters
  115. while (wildcardSearchPos < pattern.Length && justWildcardsLeft)
  116. {
  117. // Check the character at the current position
  118. char wildchar = pattern[wildcardSearchPos];
  119. // If it's not a wildcard character, then there is more
  120. // pattern information after this/these wildcards.
  121. if (wildchar != WILDCARD_CHAR && wildchar != WILDCARD_STRING)
  122. {
  123. justWildcardsLeft = false;
  124. }
  125. else
  126. {
  127. // to prevent "cat" matches "ca??"
  128. if (wildchar == WILDCARD_CHAR)
  129. {
  130. return false;
  131. }
  132. // Look at the next character
  133. wildcardSearchPos++;
  134. }
  135. }
  136. // This was a prefix wildcard search, and we've matched, so
  137. // return true.
  138. if (justWildcardsLeft)
  139. {
  140. return true;
  141. }
  142. }
  143. // If we've gone past the end of the string, or the pattern,
  144. // return false.
  145. if (sEnd || pEnd)
  146. {
  147. break;
  148. }
  149. // Match a single character, so continue.
  150. if (pattern[p] == WILDCARD_CHAR)
  151. {
  152. continue;
  153. }
  154. //
  155. if (pattern[p] == WILDCARD_STRING)
  156. {
  157. // Look at the character beyond the '*'.
  158. ++p;
  159. // Examine the string, starting at the last character.
  160. for (int i = string_Renamed.Length; i >= s; --i)
  161. {
  162. if (WildcardEquals(pattern, p, string_Renamed, i))
  163. {
  164. return true;
  165. }
  166. }
  167. break;
  168. }
  169. if (pattern[p] != string_Renamed[s])
  170. {
  171. break;
  172. }
  173. }
  174. return false;
  175. }
  176. public override void  Close()
  177. {
  178. base.Close();
  179. searchTerm = null;
  180. field = null;
  181. text = null;
  182. }
  183. }
  184. }