3 // namespace: System.Text.RegularExpressions
4 // file: quicksearch.cs
6 // Authors: Dan Lewis (dlewis@gmx.co.uk)
7 // Juraj Skripsky (juraj@hotfeet.ch)
10 // (c) 2003 Juraj Skripsky
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System
.Collections
;
37 namespace System
.Text
.RegularExpressions
{
38 internal class QuickSearch
{
39 // simplified boyer-moore for fast substring matching
40 // (for short strings, we use simple scans)
41 public QuickSearch (string str
, bool ignore
)
42 : this(str
, ignore
, false)
46 public QuickSearch (string str
, bool ignore
, bool reverse
) {
48 this.len
= str
.Length
;
50 this.reverse
= reverse
;
55 // create the shift table only for "long" search strings
60 public string String
{
68 public bool IgnoreCase
{
69 get { return ignore; }
72 public int Search (string text
, int start
, int end
) {
81 if ( ptr
> text
.Length
)
86 // use simple scan for a single-character search string
91 if(str
[0] == GetChar(text
[ptr
]))
106 while (str
[i
] == GetChar(text
[ptr
- len
+1 + i
]))
109 return ptr
- len
+ 1;
114 ptr
-= GetShiftDistance (text
[ptr
- len
]);
124 // use simple scan for a single-character search string
129 if(str
[0] == GetChar(text
[ptr
]))
137 if (end
> text
.Length
- len
)
138 end
= text
.Length
- len
;
143 while (str
[i
] == GetChar(text
[ptr
+ i
]))
150 ptr
+= GetShiftDistance (text
[ptr
+ len
]);
162 private void SetupShiftTable () {
163 shift
= new Hashtable ();
166 for (int i
= len
; i
> 0; -- i
)
169 shift
[GetChar(c
)] = i
;
174 for (int i
= 0; i
< len
; ++ i
)
177 shift
[GetChar(c
)] = len
- i
;
183 private int GetShiftDistance (char c
) {
188 return (s
!= null ? (int)s
: len
+ 1);
191 private char GetChar(char c
) {
192 return (!ignore
? c
: Char
.ToLower(c
));
198 private bool reverse
;
200 private Hashtable shift
;
201 private readonly static int THRESHOLD
= 5;