1 | /** global: UB */ |
||
2 | |||
3 | var stringFuncs = { |
||
4 | |||
5 | |||
6 | // primary search functions |
||
7 | indexOf: function(search, startAt = null){ |
||
8 | return this.smartIndexOf(search, true, true, startAt); |
||
9 | }, |
||
10 | indexOfCI: function(search, startAt = null){ |
||
11 | return this.smartIndexOf(search, false, true, startAt); |
||
12 | }, |
||
13 | smartIndexOf: function(search, caseSensitive = true, first = true, startAt = null, substringIsLower = false, wholeWords = false){ |
||
14 | var text = this; |
||
15 | |||
16 | // temps |
||
17 | var sl = search.length; |
||
18 | var ml = (text.length - sl); |
||
19 | |||
20 | // quick checks |
||
21 | if (ml < sl) { |
||
22 | return -1; |
||
23 | } |
||
24 | |||
25 | // only check equality of both strings of equal length |
||
26 | if (ml == sl) { |
||
27 | if (caseSensitive && !wholeWords) { |
||
28 | return (text == search) ? 0 : -1; |
||
29 | } |
||
30 | return text.isEqual(search, caseSensitive, false, substringIsLower) ? 0 : -1; |
||
31 | } |
||
32 | |||
33 | |||
34 | // default start at |
||
35 | if (first) { |
||
36 | if (startAt == null) { |
||
37 | startAt = 0; |
||
38 | } |
||
39 | } else { |
||
40 | if (startAt == null) { |
||
41 | startAt = ml - sl; |
||
42 | } |
||
43 | } |
||
44 | |||
45 | |||
46 | // if using whole words, slower version is used |
||
47 | if (wholeWords) { |
||
48 | var regex = UB.regex.New(search, wholeWords, caseSensitive, true); |
||
49 | if (first) { |
||
50 | var i = startAt === 0 ? text.search(regex) : text.substring(startAt).search(regex); |
||
51 | } else { |
||
52 | /*var i:int = startAt == (ml - sl) ? text.search(regex) : text.substring(startAt).search(regex);*/ |
||
53 | /// unsupported |
||
54 | i = -1; |
||
55 | } |
||
56 | return i; |
||
57 | } |
||
58 | |||
59 | |||
60 | |||
61 | if (first) { |
||
62 | |||
63 | // FIRST INDEX |
||
64 | |||
65 | // CASE INSENSITIVE |
||
66 | if (!caseSensitive) { |
||
67 | |||
68 | // very fast CI comparison |
||
69 | return text._indexOfCI(search, startAt, substringIsLower, sl, ml); |
||
70 | |||
71 | // much faster than this: |
||
72 | //return text.toUpperCase().indexOf(search.toUpperCase(), startAt); |
||
73 | } |
||
74 | |||
75 | // CASE SENSITIVE |
||
76 | return text.indexOf(search, startAt); |
||
77 | |||
78 | } |
||
79 | |||
80 | |||
81 | // LAST INDEX |
||
82 | |||
83 | // CASE INSENSITIVE |
||
84 | if (!caseSensitive) { |
||
85 | |||
86 | // very fast CI comparison |
||
87 | return text._lastIndexOfCI(search, startAt, substringIsLower, sl); |
||
88 | |||
89 | // much faster than this: |
||
90 | //return text.toUpperCase().lastIndexOf(search.toUpperCase(), startAt); |
||
91 | } |
||
92 | |||
93 | // CASE SENSITIVE |
||
94 | return text.lastIndexOf(search, startAt); |
||
95 | }, |
||
96 | |||
97 | View Code Duplication | _indexOfCI: function(search, startAt, substringIsLower, sl, ml){ |
|
98 | var text = this; |
||
99 | |||
100 | // init casing tables |
||
101 | if (UB.UTF_lowerToUpper == null){ |
||
102 | UB.initCasing(); |
||
103 | } |
||
104 | |||
105 | // per main char |
||
106 | for (var m = startAt;m <= ml;m++){ |
||
107 | |||
108 | |||
109 | // per substring char |
||
110 | var match = true; |
||
111 | for (var s = 0;s<sl;s++){ |
||
112 | |||
113 | var c1 = text.charCodeAt(m + s); |
||
114 | var c2 = search.charCodeAt(s); |
||
115 | |||
116 | // CI |
||
117 | if (c1 <= UB.UTF_casingTablesMax){ /// CI |
||
118 | c1 = UB.UTF_upperToLower[c1]; |
||
119 | } |
||
120 | if (!substringIsLower){ |
||
121 | if (c2 <= UB.UTF_casingTablesMax){ /// CI |
||
122 | c2 = UB.UTF_upperToLower[c2]; |
||
123 | } |
||
124 | } |
||
125 | |||
126 | if (c1 != c2) { |
||
127 | match = false; |
||
128 | break; |
||
129 | } |
||
130 | |||
131 | } |
||
132 | |||
133 | if (match){ |
||
134 | return m; |
||
135 | } |
||
136 | |||
137 | } |
||
138 | |||
139 | return -1; |
||
140 | }, |
||
141 | |||
142 | View Code Duplication | _lastIndexOfCI: function(search, startAt, substringIsLower, sl){ |
|
143 | var text = this; |
||
144 | |||
145 | // init casing tables |
||
146 | if (UB.UTF_lowerToUpper == null){ |
||
147 | UB.initCasing(); |
||
148 | } |
||
149 | |||
150 | // per main char |
||
151 | for (var m = startAt;m >= 0;m--){ |
||
152 | |||
153 | |||
154 | // per substring char |
||
155 | match = true; |
||
156 | for (var s = 0;s<sl;s++){ |
||
157 | |||
158 | c1 = text.charCodeAt(m + s); |
||
159 | c2 = search.charCodeAt(s); |
||
160 | |||
161 | // CI |
||
162 | if (c1 <= UB.UTF_casingTablesMax){ /// CI |
||
163 | c1 = UB.UTF_upperToLower[c1]; |
||
164 | } |
||
165 | if (!substringIsLower){ |
||
166 | if (c2 <= UB.UTF_casingTablesMax){ /// CI |
||
167 | c2 = UB.UTF_upperToLower[c2]; |
||
168 | } |
||
169 | } |
||
170 | |||
171 | if (c1 != c2) { |
||
172 | match = false; |
||
173 | break; |
||
174 | } |
||
175 | |||
176 | } |
||
177 | |||
178 | if (match){ |
||
179 | return m; |
||
180 | } |
||
181 | |||
182 | } |
||
183 | |||
184 | return -1; |
||
185 | }, |
||
186 | |||
187 | countOf: function(find, caseSensitive = true){ |
||
188 | var text = this; |
||
189 | |||
190 | // use regex method for case insensitive comparison |
||
191 | if (!caseSensitive){ |
||
192 | var char = UB.regex.Escape(find); |
||
193 | var flags = 'ig'; |
||
194 | return parseInt(text.match(new RegExp(char, flags)).length); |
||
195 | } |
||
196 | |||
197 | // use faster method for case sensitive comparison |
||
198 | var count = 0; |
||
199 | var index = 0; |
||
200 | var len = find.length; |
||
201 | while ((index = text.indexOf(find, index)) > -1) { |
||
202 | count++; |
||
203 | index += len; |
||
204 | } |
||
205 | return count; |
||
206 | }, |
||
207 | |||
208 | /** searches for all the given terms, collects their char indexes (S.IndexOf), and returns the smallest/largest index (depending on `first`) */ |
||
209 | indexOfAny: function(searchFor, first = true, caseSensitive = true, startAt = null){ |
||
210 | var str = this; |
||
211 | |||
212 | // index of first |
||
213 | if (first) { |
||
214 | return str.indexOfFirstAny(searchFor, caseSensitive, startAt); |
||
215 | } |
||
216 | |||
217 | // index of last |
||
218 | if (startAt == null) { |
||
219 | startAt = 0; |
||
220 | } |
||
221 | return str.indexOfLastAny(searchFor, caseSensitive, startAt); |
||
222 | }, |
||
223 | /** searches for all the given terms, collects their char indexes (S.IndexOf), and returns the largest index */ |
||
224 | indexOfLastAny: function(searchFor, caseSensitive = true, startAt = null){ |
||
225 | var str = this; |
||
226 | |||
227 | // case insensitive if wanted |
||
228 | if (!caseSensitive){ |
||
229 | str = str.toLowerCase(); |
||
230 | } |
||
231 | |||
232 | // per search term |
||
233 | var indices = []; |
||
234 | for (var s = 0, sl = searchFor.length;s<sl;s++){ |
||
235 | var sWord = searchFor[s]; |
||
236 | |||
237 | // case insensitive if wanted |
||
238 | if (!caseSensitive){ |
||
239 | sWord = sWord.toLowerCase(); |
||
240 | } |
||
241 | |||
242 | // check where found |
||
243 | indices[s] = str.lastIndexOf(sWord, startAt); |
||
244 | } |
||
245 | |||
246 | // return last found term |
||
247 | return indices.max(); |
||
248 | }, |
||
249 | /** searches for all the given terms, collects their char indexes (S.IndexOf), and returns the smallest index */ |
||
250 | indexOfFirstAny: function(searchFor, caseSensitive = true, startAt = 0){ |
||
251 | var str = this; |
||
252 | |||
253 | // case insensitive if wanted |
||
254 | if (!caseSensitive){ |
||
255 | str = str.toLowerCase(); |
||
256 | } |
||
257 | |||
258 | // per search term |
||
259 | var indices = []; |
||
260 | for (var s = 0, sl = searchFor.length;s<sl;s++){ |
||
261 | var sWord = searchFor[s]; |
||
262 | |||
263 | // case insensitive if wanted |
||
264 | if (!caseSensitive){ |
||
265 | sWord = sWord.toLowerCase(); |
||
266 | } |
||
267 | |||
268 | // check where found |
||
269 | indices[s] = str.indexOf(sWord, startAt); |
||
270 | |||
271 | // change -1 otherwise looks like first found term |
||
272 | if (indices[s] === -1) { |
||
273 | indices[s] = UB.intMaxValue; |
||
274 | } |
||
275 | } |
||
276 | |||
277 | // return first found term |
||
278 | return indices.min(); |
||
279 | }, |
||
280 | endIndexOfLastAny: function(searchFor, caseSensitive = true){ |
||
281 | var str = this; |
||
282 | |||
283 | // case insensitive if wanted |
||
284 | if (!caseSensitive){ |
||
285 | str = str.toLowerCase(); |
||
286 | } |
||
287 | |||
288 | // per search term |
||
289 | var indices = []; |
||
290 | for (var s = 0, sl = searchFor.length;s<sl;s++){ |
||
291 | var sWord = searchFor[s]; |
||
292 | |||
293 | // case insensitive if wanted |
||
294 | if (!caseSensitive){ |
||
295 | sWord = sWord.toLowerCase(); |
||
296 | } |
||
297 | |||
298 | // check where found |
||
299 | indices[s] = str.endIndexOfLast(sWord); |
||
300 | } |
||
301 | |||
302 | // return last found term |
||
303 | return indices.max(); |
||
304 | }, |
||
305 | endIndexOfFirstAny: function(searchFor, caseSensitive = true){ |
||
306 | var str = this; |
||
307 | |||
308 | // case insensitive if wanted |
||
309 | if (!caseSensitive){ |
||
310 | str = str.toLowerCase(); |
||
311 | } |
||
312 | |||
313 | // per search term |
||
314 | var indices = []; |
||
315 | for (var s = 0, sl = searchFor.length;s<sl;s++){ |
||
316 | var sWord = searchFor[s]; |
||
317 | |||
318 | // case insensitive if wanted |
||
319 | if (!caseSensitive){ |
||
320 | sWord = sWord.toLowerCase(); |
||
321 | } |
||
322 | |||
323 | // check where found |
||
324 | indices[s] = str.endIndexOfFirst(sWord); |
||
325 | |||
326 | // change -1 otherwise looks like first found term |
||
327 | if (indices[s] === -1) { |
||
328 | indices[s] = UB.intMaxValue; |
||
329 | } |
||
330 | } |
||
331 | |||
332 | // return first found term |
||
333 | return indices.min(); |
||
334 | }, |
||
335 | endIndexOfFirst: function(find){ |
||
336 | var str = this; |
||
337 | var pos = str.indexOf(find); |
||
338 | if (pos === -1) return -1; |
||
339 | return pos + find.length; |
||
340 | }, |
||
341 | endIndexOfLast: function(find){ |
||
342 | var str = this; |
||
343 | var pos = str.lastIndexOf(find); |
||
344 | if (pos === -1) return -1; |
||
345 | return pos + find.length; |
||
346 | }, |
||
347 | indexOfNumber: function(startAt = 0, not = false, lenIfNotFound = false){ |
||
348 | var str = this; |
||
349 | for (var c = (startAt>0?startAt:0), cl = str.length;c<cl;c++){ |
||
350 | var char = str.charAt(c); |
||
351 | if (char.isNumber() != not) { |
||
352 | return c; |
||
353 | } |
||
354 | } |
||
355 | return lenIfNotFound ? str.length : -1; |
||
356 | }, |
||
357 | indexOfAlphaNumeric: function(startAt = 0, not = false, lenIfNotFound = false){ |
||
358 | var str = this; |
||
359 | for (var c = (startAt>0?startAt:0), cl = str.length;c<cl;c++){ |
||
360 | var char = str.charAt(c); |
||
361 | if (char.isAlphaNumeric() != not) { |
||
362 | return c; |
||
363 | } |
||
364 | } |
||
365 | return lenIfNotFound ? str.length : -1; |
||
366 | }, |
||
367 | |||
368 | indexOfMany: function(find, startAt = 0){ |
||
369 | var str = this; |
||
370 | |||
371 | // returns the index, of the FIRST FOUND item in the string |
||
372 | |||
373 | var found = -1; |
||
374 | for (var f = 0, fl = find.length;f<fl;f++){ |
||
375 | var at = str.indexOf(find[f], startAt); |
||
376 | if (at != -1 && (at < found || found === -1)) { |
||
377 | found = at; |
||
378 | } |
||
379 | } |
||
380 | return found; |
||
381 | }, |
||
382 | |||
383 | |||
384 | indexOfAll: function(find, caseSensitive = true, startAt = 0, wholeWords = false){ |
||
385 | var str = this; |
||
386 | var indices = []; |
||
387 | |||
388 | var len = str.length; |
||
389 | var c = startAt; |
||
390 | while (c < len) { |
||
391 | c = str.smartIndexOf(find, caseSensitive, true, c, false, wholeWords); |
||
392 | if (c === -1) { |
||
393 | break; |
||
394 | } |
||
395 | indices.push(c); |
||
396 | c += find.length; |
||
397 | } |
||
398 | |||
399 | return indices; |
||
400 | }, |
||
401 | |||
402 | findAll: function(find){ |
||
403 | var str = this.toString(); |
||
404 | var matches = []; |
||
405 | |||
406 | // if regex return all matches |
||
407 | if (find.isRegex()){ |
||
408 | do { |
||
409 | var match = find.exec(str); |
||
410 | if (match) { |
||
411 | matches.push(match); |
||
412 | } |
||
413 | } while (match); |
||
414 | } |
||
415 | |||
416 | // if string find and return all matches |
||
417 | if (find.isString()){ |
||
418 | var indices = str.indexOfAll(); |
||
419 | for (var i=0; i<indices.length; i++){ |
||
420 | var index = indices[i]; |
||
421 | var match = {startIndex:index, endIndex:index+find.length, text:find}; |
||
0 ignored issues
–
show
|
|||
422 | } |
||
423 | } |
||
424 | |||
425 | return matches; |
||
426 | }, |
||
427 | |||
428 | indexOfNth(search, nth, wholeWords = false, matchCase = true) { |
||
429 | var text = this.toString(); |
||
430 | |||
431 | // quickly test if text contains wanted var |
||
432 | if (!matchCase || text.contains(search)) { |
||
433 | |||
434 | // create regex to find |
||
435 | var regex = UB.regex.New(search, wholeWords, matchCase); |
||
436 | |||
437 | |||
438 | // find and return index if found |
||
439 | var match = null; |
||
440 | for (var n = 0; n < nth; n++) { |
||
441 | match = regex.exec(text); |
||
442 | if (match == null || match < 0) { |
||
443 | return -1; |
||
444 | } else { |
||
0 ignored issues
–
show
Comprehensibility
Documentation
Best Practice
introduced
by
|
|||
445 | //startAt = match + 1; |
||
446 | } |
||
447 | } |
||
448 | return match == null ? -1 : match; |
||
449 | } |
||
450 | |||
451 | return -1; |
||
452 | }, |
||
453 | |||
454 | |||
455 | none:null |
||
456 | }; |
||
457 | |||
458 | // register funcs |
||
459 | UB.registerFuncs(String.prototype, stringFuncs); |
This check looks for variables that are declared in multiple lines. There may be several reasons for this.
In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.
If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.