001package Torello.Java;
002
003import java.util.Vector;
004import java.util.stream.IntStream;
005
006/**
007 * This class builds upon the API that is provided by {@code String indexOf} to provide a
008 * larger collection of search routines for Java {@code String's}.
009 * 
010 * <EMBED CLASS='external-html' DATA-FILE-ID=STR_INDEX_OF>
011 */
012@Torello.JavaDoc.StaticFunctional
013@Torello.JavaDoc.JDHeaderBackgroundImg
014public class StrIndexOf
015{
016    private StrIndexOf() { }
017
018    /**
019     * Search for <B STYLE='color: red'>all</B> occurences of character {@code 'c'}
020     * in {@code 'srcStr'}, and return an integer-array of index-locations into {@code 'srcStr.'}
021     * 
022     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
023     * 
024     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
025     * 
026     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
027     * for the specified matches, and an integer-array of {@code String}-index pointers
028     * will be returned.
029     * 
030     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
031     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
032     * 
033     * @param c This is the character that will be 'searched-for' in input-parameter
034     * {@code String 'srcStr'}.
035     * 
036     * @return An integer-pointer array of <B STYLE='color: red'>all</B>
037     * {@code java.lang.String}-indices where matches were found.
038     * 
039     * @throws StringIndexOutOfBoundsException
040     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
041     */
042    public static int[] all_CI(String srcStr, int sPos, int ePos, char c)
043    {
044        LV                  l = new LV(srcStr, sPos, ePos);
045        IntStream.Builder   b = IntStream.builder();
046
047        c = Character.toLowerCase(c);
048
049        for (int i=l.start; i < l.end; i++)
050            if (c == Character.toLowerCase(srcStr.charAt(i))) b.accept(i);
051
052        return b.build().toArray();
053    }
054
055    /**
056     * Search for <B STYLE='color: red'>all</B> occurences of substring {@code 'cmpStr'}
057     * in {@code 'srcStr'}, and return an integer-array of index-locations into {@code 'srcStr.'}
058     * 
059     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
060     * 
061     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
062     * 
063     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
064     * for the specified matches, and an integer-array of {@code String}-index pointers
065     * will be returned.
066     * 
067     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
068     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
069     * 
070     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
071     * {@code String 'srcStr'}.
072     * 
073     * @return An integer-pointer array of <B STYLE='color: red'>all</B>
074     * {@code java.lang.String}-indices where matches were found.
075     * 
076     * @throws StringIndexOutOfBoundsException
077     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
078     */
079    public static int[] all_CI(String srcStr, int sPos, int ePos, String cmpStr)
080    {
081        LV                  l           = new LV(srcStr, sPos, ePos, cmpStr.length());
082        IntStream.Builder   b           = IntStream.builder();
083        int                 cmpStrLen   = cmpStr.length();
084
085        for (int i=l.start; i < l.end; i++)
086            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) b.accept(i);
087
088        return b.build().toArray();
089    }
090
091    /**
092     * Search for <B STYLE='color: red'>all</B> occurences of character {@code 'c'}
093     * in {@code 'srcStr'}, and return an integer-array of index-locations into {@code 'srcStr.'}
094     * 
095     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
096     * 
097     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
098     * for the specified matches, and an integer-array of {@code String}-index pointers
099     * will be returned.
100     * 
101     * @param c This is the character that will be 'searched-for' in input-parameter
102     * {@code String 'srcStr'}.
103     * 
104     * @return An integer-pointer array of <B STYLE='color: red'>all</B>
105     * {@code java.lang.String}-indices where matches were found.
106     */
107    public static int[] all_CI(String srcStr, char c)
108    {
109        LV                  l = new LV(srcStr, 0, -1);
110        IntStream.Builder   b = IntStream.builder();
111
112        c = Character.toLowerCase(c);
113
114        for (int i=l.start; i < l.end; i++)
115            if (c == Character.toLowerCase(srcStr.charAt(i))) b.accept(i);
116
117        return b.build().toArray();
118    }
119
120    /**
121     * Search for <B STYLE='color: red'>all</B> occurences of substring {@code 'cmpStr'}
122     * in {@code 'srcStr'}, and return an integer-array of index-locations into {@code 'srcStr.'}
123     * 
124     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
125     * 
126     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
127     * for the specified matches, and an integer-array of {@code String}-index pointers
128     * will be returned.
129     * 
130     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
131     * {@code String 'srcStr'}.
132     * 
133     * @return An integer-pointer array of <B STYLE='color: red'>all</B>
134     * {@code java.lang.String}-indices where matches were found.
135     */
136    public static int[] all_CI(String srcStr, String cmpStr)
137    {
138        LV                  l           = new LV(srcStr, 0, -1, cmpStr.length());
139        IntStream.Builder   b           = IntStream.builder();
140        int                 cmpStrLen   = cmpStr.length();
141
142        for (int i=l.start; i < l.end; i++)
143            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) b.accept(i);
144
145        return b.build().toArray();
146    }
147
148    /**
149     * Search for <B STYLE='color: red'>all</B> occurences of character {@code 'c'}
150     * in {@code 'srcStr'}, and return an integer-array of index-locations into {@code 'srcStr.'}
151     * 
152     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
153     * 
154     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
155     * 
156     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
157     * for the specified matches, and an integer-array of {@code String}-index pointers
158     * will be returned.
159     * 
160     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
161     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
162     * 
163     * @param c This is the character that will be 'searched-for' in input-parameter
164     * {@code String 'srcStr'}.
165     * 
166     * @return An integer-pointer array of <B STYLE='color: red'>all</B>
167     * {@code java.lang.String}-indices where matches were found.
168     * 
169     * @throws StringIndexOutOfBoundsException
170     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
171     */
172    public static int[] all(String srcStr, int sPos, int ePos, char c)
173    {
174        LV                  l = new LV(srcStr, sPos, ePos);
175        IntStream.Builder   b = IntStream.builder();
176
177        for (int i=l.start; i < l.end; i++)
178            if (c == srcStr.charAt(i)) b.accept(i);
179
180        return b.build().toArray();
181    }
182
183    /**
184     * Search for <B STYLE='color: red'>all</B> occurences of substring {@code 'cmpStr'}
185     * in {@code 'srcStr'}, and return an integer-array of index-locations into {@code 'srcStr.'}
186     * 
187     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
188     * 
189     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
190     * 
191     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
192     * for the specified matches, and an integer-array of {@code String}-index pointers
193     * will be returned.
194     * 
195     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
196     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
197     * 
198     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
199     * {@code String 'srcStr'}.
200     * 
201     * @return An integer-pointer array of <B STYLE='color: red'>all</B>
202     * {@code java.lang.String}-indices where matches were found.
203     * 
204     * @throws StringIndexOutOfBoundsException
205     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
206     */
207    public static int[] all(String srcStr, int sPos, int ePos, String cmpStr)
208    {
209        LV                  l           = new LV(srcStr, sPos, ePos, cmpStr.length());
210        IntStream.Builder   b           = IntStream.builder();
211        int                 cmpStrLen   = cmpStr.length();
212
213        for (int i=l.start; i < l.end; i++)
214            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) b.accept(i);
215
216        return b.build().toArray();
217    }
218
219    /**
220     * Search for <B STYLE='color: red'>all</B> occurences of character {@code 'c'}
221     * in {@code 'srcStr'}, and return an integer-array of index-locations into {@code 'srcStr.'}
222     * 
223     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
224     * 
225     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
226     * for the specified matches, and an integer-array of {@code String}-index pointers
227     * will be returned.
228     * 
229     * @param c This is the character that will be 'searched-for' in input-parameter
230     * {@code String 'srcStr'}.
231     * 
232     * @return An integer-pointer array of <B STYLE='color: red'>all</B>
233     * {@code java.lang.String}-indices where matches were found.
234     */
235    public static int[] all(String srcStr, char c)
236    {
237        LV                  l = new LV(srcStr, 0, -1);
238        IntStream.Builder   b = IntStream.builder();
239
240        for (int i=l.start; i < l.end; i++)
241            if (c == srcStr.charAt(i)) b.accept(i);
242
243        return b.build().toArray();
244    }
245
246    /**
247     * Search for <B STYLE='color: red'>all</B> occurences of substring {@code 'cmpStr'}
248     * in {@code 'srcStr'}, and return an integer-array of index-locations into {@code 'srcStr.'}
249     * 
250     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
251     * 
252     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
253     * for the specified matches, and an integer-array of {@code String}-index pointers
254     * will be returned.
255     * 
256     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
257     * {@code String 'srcStr'}.
258     * 
259     * @return An integer-pointer array of <B STYLE='color: red'>all</B>
260     * {@code java.lang.String}-indices where matches were found.
261     */
262    public static int[] all(String srcStr, String cmpStr)
263    {
264        LV                  l           = new LV(srcStr, 0, -1, cmpStr.length());
265        IntStream.Builder   b           = IntStream.builder();
266        int                 cmpStrLen   = cmpStr.length();
267
268        for (int i=l.start; i < l.end; i++)
269            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) b.accept(i);
270
271        return b.build().toArray();
272    }
273
274    /**
275     * Search for the <B STYLE='color: red'>first</B> occurence of character {@code 'c'}
276     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
277     * match occured.
278     * 
279     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
280     * 
281     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
282     * 
283     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
284     * for the specified matches, and an index-pointer as an integer will be returned.
285     * 
286     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
287     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
288     * 
289     * @param c This is the character that will be 'searched-for' in input-parameter
290     * {@code String 'srcStr'}.
291     * 
292     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
293     * sub-string match in {@code 'srcStr'}
294     * 
295     * @throws StringIndexOutOfBoundsException
296     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
297     */
298    public static int first_CI(String srcStr, int sPos, int ePos, char c)
299    {
300        LV l = new LV(srcStr, sPos, ePos);
301
302        c = Character.toLowerCase(c);
303
304        for (int i=l.start; i < l.end; i++)
305            if (c == Character.toLowerCase(srcStr.charAt(i))) return i;
306
307        return -1;
308    }
309
310    /**
311     * Search for the <B STYLE='color: red'>first</B> occurence of substring {@code 'cmpStr'}
312     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
313     * match occured.
314     * 
315     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
316     * 
317     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
318     * 
319     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
320     * for the specified matches, and an index-pointer as an integer will be returned.
321     * 
322     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
323     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
324     * 
325     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
326     * {@code String 'srcStr'}.
327     * 
328     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
329     * sub-string match in {@code 'srcStr'}
330     * 
331     * @throws StringIndexOutOfBoundsException
332     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
333     */
334    public static int first_CI(String srcStr, int sPos, int ePos, String cmpStr)
335    {
336        LV  l           = new LV(srcStr, sPos, ePos, cmpStr.length());
337        int cmpStrLen   = cmpStr.length();
338
339        for (int i=l.start; i < l.end; i++)
340            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) return i;
341
342        return -1;
343    }
344
345    /**
346     * Search for the <B STYLE='color: red'>first</B> occurence of character {@code 'c'}
347     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
348     * match occured.
349     * 
350     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
351     * 
352     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
353     * for the specified matches, and an index-pointer as an integer will be returned.
354     * 
355     * @param c This is the character that will be 'searched-for' in input-parameter
356     * {@code String 'srcStr'}.
357     * 
358     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
359     * sub-string match in {@code 'srcStr'}
360     */
361    public static int first_CI(String srcStr, char c)
362    {
363        LV l = new LV(srcStr, 0, -1);
364
365        c = Character.toLowerCase(c);
366
367        for (int i=l.start; i < l.end; i++)
368            if (c == Character.toLowerCase(srcStr.charAt(i))) return i;
369
370        return -1;
371    }
372
373    /**
374     * Search for the <B STYLE='color: red'>first</B> occurence of substring {@code 'cmpStr'}
375     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
376     * match occured.
377     * 
378     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
379     * 
380     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
381     * for the specified matches, and an index-pointer as an integer will be returned.
382     * 
383     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
384     * {@code String 'srcStr'}.
385     * 
386     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
387     * sub-string match in {@code 'srcStr'}
388     */
389    public static int first_CI(String srcStr, String cmpStr)
390    {
391        LV  l           = new LV(srcStr, 0, -1, cmpStr.length());
392        int cmpStrLen   = cmpStr.length();
393
394        for (int i=l.start; i < l.end; i++)
395            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) return i;
396
397        return -1;
398    }
399
400    /**
401     * Search for the <B STYLE='color: red'>first</B> occurence of character {@code 'c'}
402     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
403     * match occured.
404     * 
405     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
406     * 
407     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
408     * 
409     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
410     * for the specified matches, and an index-pointer as an integer will be returned.
411     * 
412     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
413     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
414     * 
415     * @param c This is the character that will be 'searched-for' in input-parameter
416     * {@code String 'srcStr'}.
417     * 
418     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
419     * sub-string match in {@code 'srcStr'}
420     * 
421     * @throws StringIndexOutOfBoundsException
422     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
423     */
424    public static int first(String srcStr, int sPos, int ePos, char c)
425    {
426        LV l = new LV(srcStr, sPos, ePos);
427
428        for (int i=l.start; i < l.end; i++)
429            if (c == srcStr.charAt(i)) return i;
430
431        return -1;
432    }
433
434    /**
435     * Search for the <B STYLE='color: red'>first</B> occurence of substring {@code 'cmpStr'}
436     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
437     * match occured.
438     * 
439     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
440     * 
441     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
442     * 
443     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
444     * for the specified matches, and an index-pointer as an integer will be returned.
445     * 
446     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
447     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
448     * 
449     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
450     * {@code String 'srcStr'}.
451     * 
452     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
453     * sub-string match in {@code 'srcStr'}
454     * 
455     * @throws StringIndexOutOfBoundsException
456     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
457     */
458    public static int first(String srcStr, int sPos, int ePos, String cmpStr)
459    {
460        LV  l           = new LV(srcStr, sPos, ePos, cmpStr.length());
461        int cmpStrLen   = cmpStr.length();
462
463        for (int i=l.start; i < l.end; i++)
464            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) return i;
465
466        return -1;
467    }
468
469    /**
470     * Search for the <B STYLE='color: red'>first</B> occurence of character {@code 'c'}
471     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
472     * match occured.
473     * 
474     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
475     * 
476     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
477     * for the specified matches, and an index-pointer as an integer will be returned.
478     * 
479     * @param c This is the character that will be 'searched-for' in input-parameter
480     * {@code String 'srcStr'}.
481     * 
482     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
483     * sub-string match in {@code 'srcStr'}
484     */
485    public static int first(String srcStr, char c)
486    {
487        LV l = new LV(srcStr, 0, -1);
488
489        for (int i=l.start; i < l.end; i++)
490            if (c == srcStr.charAt(i)) return i;
491
492        return -1;
493    }
494
495    /**
496     * Search for the <B STYLE='color: red'>first</B> occurence of substring {@code 'cmpStr'}
497     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
498     * match occured.
499     * 
500     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
501     * 
502     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
503     * for the specified matches, and an index-pointer as an integer will be returned.
504     * 
505     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
506     * {@code String 'srcStr'}.
507     * 
508     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
509     * sub-string match in {@code 'srcStr'}
510     */
511    public static int first(String srcStr, String cmpStr)
512    {
513        LV  l           = new LV(srcStr, 0, -1, cmpStr.length());
514        int cmpStrLen   = cmpStr.length();
515
516        for (int i=l.start; i < l.end; i++)
517            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) return i;
518
519        return -1;
520    }
521
522    /**
523     * Search for the <B STYLE='color: red'>last</B> occurence of character {@code 'c'}
524     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
525     * match occured.
526     * 
527     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
528     * 
529     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
530     * 
531     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
532     * for the specified matches, and an index-pointer as an integer will be returned.
533     * 
534     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
535     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
536     * 
537     * @param c This is the character that will be 'searched-for' in input-parameter
538     * {@code String 'srcStr'}.
539     * 
540     * @return The {@code String} index of the <B STYLE='color: red'>last</B> identified
541     * sub-string match in {@code 'srcStr'}
542     * 
543     * @throws StringIndexOutOfBoundsException
544     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
545     */
546    public static int last_CI(String srcStr, int sPos, int ePos, char c)
547    {
548        LV l = new LV(srcStr, sPos, ePos);
549
550        c = Character.toLowerCase(c);
551
552        for (int i=(l.end-1); i >= l.start; i--)
553            if (c == Character.toLowerCase(srcStr.charAt(i))) return i;
554
555        return -1;
556    }
557
558    /**
559     * Search for the <B STYLE='color: red'>last</B> occurence of substring {@code 'cmpStr'}
560     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
561     * match occured.
562     * 
563     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
564     * 
565     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
566     * 
567     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
568     * for the specified matches, and an index-pointer as an integer will be returned.
569     * 
570     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
571     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
572     * 
573     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
574     * {@code String 'srcStr'}.
575     * 
576     * @return The {@code String} index of the <B STYLE='color: red'>last</B> identified
577     * sub-string match in {@code 'srcStr'}
578     * 
579     * @throws StringIndexOutOfBoundsException
580     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
581     */
582    public static int last_CI(String srcStr, int sPos, int ePos, String cmpStr)
583    {
584        LV  l           = new LV(srcStr, sPos, ePos, cmpStr.length());
585        int cmpStrLen   = cmpStr.length();
586
587        for (int i=(l.end-1); i >= l.start; i--)
588            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) return i;
589
590        return -1;
591    }
592
593    /**
594     * Search for the <B STYLE='color: red'>last</B> occurence of character {@code 'c'}
595     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
596     * match occured.
597     * 
598     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
599     * 
600     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
601     * for the specified matches, and an index-pointer as an integer will be returned.
602     * 
603     * @param c This is the character that will be 'searched-for' in input-parameter
604     * {@code String 'srcStr'}.
605     * 
606     * @return The {@code String} index of the <B STYLE='color: red'>last</B> identified
607     * sub-string match in {@code 'srcStr'}
608     */
609    public static int last_CI(String srcStr, char c)
610    {
611        LV l = new LV(srcStr, 0, -1);
612
613        c = Character.toLowerCase(c);
614
615        for (int i=(l.end-1); i >= l.start; i--)
616            if (c == Character.toLowerCase(srcStr.charAt(i))) return i;
617
618        return -1;
619    }
620
621    /**
622     * Search for the <B STYLE='color: red'>last</B> occurence of substring {@code 'cmpStr'}
623     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
624     * match occured.
625     * 
626     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
627     * 
628     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
629     * for the specified matches, and an index-pointer as an integer will be returned.
630     * 
631     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
632     * {@code String 'srcStr'}.
633     * 
634     * @return The {@code String} index of the <B STYLE='color: red'>last</B> identified
635     * sub-string match in {@code 'srcStr'}
636     */
637    public static int last_CI(String srcStr, String cmpStr)
638    {
639        LV  l           = new LV(srcStr, 0, -1, cmpStr.length());
640        int cmpStrLen   = cmpStr.length();
641
642        for (int i=(l.end-1); i >= l.start; i--)
643            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) return i;
644
645        return -1;
646    }
647
648    /**
649     * Search for the <B STYLE='color: red'>last</B> occurence of character {@code 'c'}
650     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
651     * match occured.
652     * 
653     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
654     * 
655     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
656     * 
657     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
658     * for the specified matches, and an index-pointer as an integer will be returned.
659     * 
660     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
661     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
662     * 
663     * @param c This is the character that will be 'searched-for' in input-parameter
664     * {@code String 'srcStr'}.
665     * 
666     * @return The {@code String} index of the <B STYLE='color: red'>last</B> identified
667     * sub-string match in {@code 'srcStr'}
668     * 
669     * @throws StringIndexOutOfBoundsException
670     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
671     */
672    public static int last(String srcStr, int sPos, int ePos, char c)
673    {
674        LV l = new LV(srcStr, sPos, ePos);
675
676        for (int i=(l.end-1); i >= l.start; i--)
677            if (c == srcStr.charAt(i)) return i;
678
679        return -1;
680    }
681
682    /**
683     * Search for the <B STYLE='color: red'>last</B> occurence of substring {@code 'cmpStr'}
684     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
685     * match occured.
686     * 
687     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
688     * 
689     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
690     * 
691     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
692     * for the specified matches, and an index-pointer as an integer will be returned.
693     * 
694     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
695     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
696     * 
697     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
698     * {@code String 'srcStr'}.
699     * 
700     * @return The {@code String} index of the <B STYLE='color: red'>last</B> identified
701     * sub-string match in {@code 'srcStr'}
702     * 
703     * @throws StringIndexOutOfBoundsException
704     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
705     */
706    public static int last(String srcStr, int sPos, int ePos, String cmpStr)
707    {
708        LV  l           = new LV(srcStr, sPos, ePos, cmpStr.length());
709        int cmpStrLen   = cmpStr.length();
710
711        for (int i=(l.end-1); i >= l.start; i--)
712            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) return i;
713
714        return -1;
715    }
716
717    /**
718     * Search for the <B STYLE='color: red'>last</B> occurence of character {@code 'c'}
719     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
720     * match occured.
721     * 
722     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
723     * 
724     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
725     * for the specified matches, and an index-pointer as an integer will be returned.
726     * 
727     * @param c This is the character that will be 'searched-for' in input-parameter
728     * {@code String 'srcStr'}.
729     * 
730     * @return The {@code String} index of the <B STYLE='color: red'>last</B> identified
731     * sub-string match in {@code 'srcStr'}
732     */
733    public static int last(String srcStr, char c)
734    {
735        LV l = new LV(srcStr, 0, -1);
736
737        for (int i=(l.end-1); i >= l.start; i--)
738            if (c == srcStr.charAt(i)) return i;
739
740        return -1;
741    }
742
743    /**
744     * Search for the <B STYLE='color: red'>last</B> occurence of substring {@code 'cmpStr'}
745     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
746     * match occured.
747     * 
748     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
749     * 
750     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
751     * for the specified matches, and an index-pointer as an integer will be returned.
752     * 
753     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
754     * {@code String 'srcStr'}.
755     * 
756     * @return The {@code String} index of the <B STYLE='color: red'>last</B> identified
757     * sub-string match in {@code 'srcStr'}
758     */
759    public static int last(String srcStr, String cmpStr)
760    {
761        LV  l           = new LV(srcStr, 0, -1, cmpStr.length());
762        int cmpStrLen   = cmpStr.length();
763
764        for (int i=(l.end-1); i >= l.start; i--)
765            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) return i;
766
767        return -1;
768    }
769
770    /**
771     * Search for the <B STYLE='color: red'>nth</B> occurence of character {@code 'c'}
772     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
773     * match occured.
774     * 
775     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
776     * 
777     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
778     * 
779     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
780     * for the specified matches, and an index-pointer as an integer will be returned.
781     * 
782     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
783     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
784     * 
785     * @param n This is the number of matches to skip when searching for character {@code 'c'}
786     * before returning an answer.
787     * 
788     * @param c This is the character that will be 'searched-for' in input-parameter
789     * {@code String 'srcStr'}.
790     * 
791     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
792     * match in {@code 'srcStr'}
793     * 
794     * @throws StringIndexOutOfBoundsException
795     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
796     * 
797     * @throws NException If the value of {@code 'n'} is negative, or greater than
798     * {@code srcStr.length()}, this exception shall throw.
799     */
800    public static int nth_CI(String srcStr, int sPos, int ePos, int n, char c)
801    {
802        NException.check(n, srcStr);
803
804        LV l = new LV(srcStr, sPos, ePos);
805
806        c = Character.toLowerCase(c);
807
808        for (int i=l.start; i < l.end; i++)
809            if (c == Character.toLowerCase(srcStr.charAt(i))) if (--n == 0) return i;
810
811        return -1;
812    }
813
814    /**
815     * Search for the <B STYLE='color: red'>nth</B> occurence of substring {@code 'cmpStr'}
816     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
817     * match occured.
818     * 
819     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
820     * 
821     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
822     * 
823     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
824     * for the specified matches, and an index-pointer as an integer will be returned.
825     * 
826     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
827     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
828     * 
829     * @param n This is the number of matches to skip when searching for substring {@code 'cmpStr'}
830     * before returning an answer.
831     * 
832     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
833     * {@code String 'srcStr'}.
834     * 
835     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
836     * match in {@code 'srcStr'}
837     * 
838     * @throws StringIndexOutOfBoundsException
839     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
840     * 
841     * @throws NException If the value of {@code 'n'} is negative, or greater than
842     * {@code srcStr.length()}, this exception shall throw.
843     */
844    public static int nth_CI(String srcStr, int sPos, int ePos, int n, String cmpStr)
845    {
846        NException.check(n, srcStr);
847
848        LV  l           = new LV(srcStr, sPos, ePos, cmpStr.length());
849        int cmpStrLen   = cmpStr.length();
850
851        for (int i=l.start; i < l.end; i++)
852            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) if (--n == 0) return i;
853
854        return -1;
855    }
856
857    /**
858     * Search for the <B STYLE='color: red'>nth</B> occurence of character {@code 'c'}
859     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
860     * match occured.
861     * 
862     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
863     * 
864     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
865     * for the specified matches, and an index-pointer as an integer will be returned.
866     * 
867     * @param n This is the number of matches to skip when searching for character {@code 'c'}
868     * before returning an answer.
869     * 
870     * @param c This is the character that will be 'searched-for' in input-parameter
871     * {@code String 'srcStr'}.
872     * 
873     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
874     * match in {@code 'srcStr'}
875     * 
876     * @throws NException If the value of {@code 'n'} is negative, or greater than
877     * {@code srcStr.length()}, this exception shall throw.
878     */
879    public static int nth_CI(String srcStr, int n, char c)
880    {
881        NException.check(n, srcStr);
882
883        LV l = new LV(srcStr, 0, -1);
884
885        c = Character.toLowerCase(c);
886
887        for (int i=l.start; i < l.end; i++)
888            if (c == Character.toLowerCase(srcStr.charAt(i))) if (--n == 0) return i;
889
890        return -1;
891    }
892
893    /**
894     * Search for the <B STYLE='color: red'>nth</B> occurence of substring {@code 'cmpStr'}
895     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
896     * match occured.
897     * 
898     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
899     * 
900     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
901     * for the specified matches, and an index-pointer as an integer will be returned.
902     * 
903     * @param n This is the number of matches to skip when searching for substring {@code 'cmpStr'}
904     * before returning an answer.
905     * 
906     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
907     * {@code String 'srcStr'}.
908     * 
909     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
910     * match in {@code 'srcStr'}
911     * 
912     * @throws NException If the value of {@code 'n'} is negative, or greater than
913     * {@code srcStr.length()}, this exception shall throw.
914     */
915    public static int nth_CI(String srcStr, int n, String cmpStr)
916    {
917        NException.check(n, srcStr);
918
919        LV  l           = new LV(srcStr, 0, -1, cmpStr.length());
920        int cmpStrLen   = cmpStr.length();
921
922        for (int i=l.start; i < l.end; i++)
923            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) if (--n == 0) return i;
924
925        return -1;
926    }
927
928    /**
929     * Search for the <B STYLE='color: red'>nth</B> occurence of character {@code 'c'}
930     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
931     * match occured.
932     * 
933     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
934     * 
935     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
936     * 
937     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
938     * for the specified matches, and an index-pointer as an integer will be returned.
939     * 
940     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
941     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
942     * 
943     * @param n This is the number of matches to skip when searching for character {@code 'c'}
944     * before returning an answer.
945     * 
946     * @param c This is the character that will be 'searched-for' in input-parameter
947     * {@code String 'srcStr'}.
948     * 
949     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
950     * match in {@code 'srcStr'}
951     * 
952     * @throws StringIndexOutOfBoundsException
953     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
954     * 
955     * @throws NException If the value of {@code 'n'} is negative, or greater than
956     * {@code srcStr.length()}, this exception shall throw.
957     */
958    public static int nth(String srcStr, int sPos, int ePos, int n, char c)
959    {
960        NException.check(n, srcStr);
961
962        LV l = new LV(srcStr, sPos, ePos);
963
964        for (int i=l.start; i < l.end; i++)
965            if (c == srcStr.charAt(i)) if (--n == 0) return i;
966
967        return -1;
968    }
969
970    /**
971     * Search for the <B STYLE='color: red'>nth</B> occurence of substring {@code 'cmpStr'}
972     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
973     * match occured.
974     * 
975     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
976     * 
977     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
978     * 
979     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
980     * for the specified matches, and an index-pointer as an integer will be returned.
981     * 
982     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
983     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
984     * 
985     * @param n This is the number of matches to skip when searching for substring {@code 'cmpStr'}
986     * before returning an answer.
987     * 
988     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
989     * {@code String 'srcStr'}.
990     * 
991     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
992     * match in {@code 'srcStr'}
993     * 
994     * @throws StringIndexOutOfBoundsException
995     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
996     * 
997     * @throws NException If the value of {@code 'n'} is negative, or greater than
998     * {@code srcStr.length()}, this exception shall throw.
999     */
1000    public static int nth(String srcStr, int sPos, int ePos, int n, String cmpStr)
1001    {
1002        NException.check(n, srcStr);
1003
1004        LV  l           = new LV(srcStr, sPos, ePos, cmpStr.length());
1005        int cmpStrLen   = cmpStr.length();
1006
1007        for (int i=l.start; i < l.end; i++)
1008            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) if (--n == 0) return i;
1009
1010        return -1;
1011    }
1012
1013    /**
1014     * Search for the <B STYLE='color: red'>nth</B> occurence of character {@code 'c'}
1015     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
1016     * match occured.
1017     * 
1018     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
1019     * 
1020     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1021     * for the specified matches, and an index-pointer as an integer will be returned.
1022     * 
1023     * @param n This is the number of matches to skip when searching for character {@code 'c'}
1024     * before returning an answer.
1025     * 
1026     * @param c This is the character that will be 'searched-for' in input-parameter
1027     * {@code String 'srcStr'}.
1028     * 
1029     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1030     * match in {@code 'srcStr'}
1031     * 
1032     * @throws NException If the value of {@code 'n'} is negative, or greater than
1033     * {@code srcStr.length()}, this exception shall throw.
1034     */
1035    public static int nth(String srcStr, int n, char c)
1036    {
1037        NException.check(n, srcStr);
1038
1039        LV l = new LV(srcStr, 0, -1);
1040
1041        for (int i=l.start; i < l.end; i++)
1042            if (c == srcStr.charAt(i)) if (--n == 0) return i;
1043
1044        return -1;
1045    }
1046
1047    /**
1048     * Search for the <B STYLE='color: red'>nth</B> occurence of substring {@code 'cmpStr'}
1049     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
1050     * match occured.
1051     * 
1052     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
1053     * 
1054     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1055     * for the specified matches, and an index-pointer as an integer will be returned.
1056     * 
1057     * @param n This is the number of matches to skip when searching for substring {@code 'cmpStr'}
1058     * before returning an answer.
1059     * 
1060     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
1061     * {@code String 'srcStr'}.
1062     * 
1063     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1064     * match in {@code 'srcStr'}
1065     * 
1066     * @throws NException If the value of {@code 'n'} is negative, or greater than
1067     * {@code srcStr.length()}, this exception shall throw.
1068     */
1069    public static int nth(String srcStr, int n, String cmpStr)
1070    {
1071        NException.check(n, srcStr);
1072
1073        LV  l           = new LV(srcStr, 0, -1, cmpStr.length());
1074        int cmpStrLen   = cmpStr.length();
1075
1076        for (int i=l.start; i < l.end; i++)
1077            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) if (--n == 0) return i;
1078
1079        return -1;
1080    }
1081
1082    /**
1083     * Search for the <B STYLE='color: red'>nth</B> occurence of character {@code 'c'}, but
1084     * start the search with the <I>last character of the String and work
1085     * <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into {@code 'srcStr'}
1086     * where the match occured.
1087     * 
1088     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
1089     * 
1090     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
1091     * 
1092     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1093     * for the specified matches, and an index-pointer as an integer will be returned.
1094     * 
1095     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
1096     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
1097     * 
1098     * @param n This is the number of matches to skip when searching for character {@code 'c'}
1099     * before returning an answer.
1100     * 
1101     * @param c This is the character that will be 'searched-for' in input-parameter
1102     * {@code String 'srcStr'}.
1103     * 
1104     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1105     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> from the end of
1106     * {@code 'srcStr'}</I>
1107     * 
1108     * @throws StringIndexOutOfBoundsException
1109     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
1110     * 
1111     * @throws NException If the value of {@code 'n'} is negative, or greater than
1112     * {@code srcStr.length()}, this exception shall throw.
1113     */
1114    public static int nthFromEnd_CI(String srcStr, int sPos, int ePos, int n, char c)
1115    {
1116        NException.check(n, srcStr);
1117
1118        LV l = new LV(srcStr, sPos, ePos);
1119
1120        c = Character.toLowerCase(c);
1121
1122        for (int i=(l.end-1); i >= l.start; i--)
1123            if (c == Character.toLowerCase(srcStr.charAt(i))) if (--n == 0) return i;
1124
1125        return -1;
1126    }
1127
1128    /**
1129     * Search for the <B STYLE='color: red'>nth</B> occurence of substring {@code 'cmpStr'}, but
1130     * start the search with the <I>last character of the String and work
1131     * <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into {@code 'srcStr'}
1132     * where the match occured.
1133     * 
1134     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
1135     * 
1136     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
1137     * 
1138     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1139     * for the specified matches, and an index-pointer as an integer will be returned.
1140     * 
1141     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
1142     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
1143     * 
1144     * @param n This is the number of matches to skip when searching for substring {@code 'cmpStr'}
1145     * before returning an answer.
1146     * 
1147     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
1148     * {@code String 'srcStr'}.
1149     * 
1150     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1151     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> from the end of
1152     * {@code 'srcStr'}</I>
1153     * 
1154     * @throws StringIndexOutOfBoundsException
1155     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
1156     * 
1157     * @throws NException If the value of {@code 'n'} is negative, or greater than
1158     * {@code srcStr.length()}, this exception shall throw.
1159     */
1160    public static int nthFromEnd_CI(String srcStr, int sPos, int ePos, int n, String cmpStr)
1161    {
1162        NException.check(n, srcStr);
1163
1164        LV  l           = new LV(srcStr, sPos, ePos, cmpStr.length());
1165        int cmpStrLen   = cmpStr.length();
1166
1167        for (int i=(l.end-1); i >= l.start; i--)
1168            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) if (--n == 0) return i;
1169
1170        return -1;
1171    }
1172
1173    /**
1174     * Search for the <B STYLE='color: red'>nth</B> occurence of character {@code 'c'}, but
1175     * start the search with the <I>last character of the String and work
1176     * <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into {@code 'srcStr'}
1177     * where the match occured.
1178     * 
1179     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
1180     * 
1181     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1182     * for the specified matches, and an index-pointer as an integer will be returned.
1183     * 
1184     * @param n This is the number of matches to skip when searching for character {@code 'c'}
1185     * before returning an answer.
1186     * 
1187     * @param c This is the character that will be 'searched-for' in input-parameter
1188     * {@code String 'srcStr'}.
1189     * 
1190     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1191     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> from the end of
1192     * {@code 'srcStr'}</I>
1193     * 
1194     * @throws NException If the value of {@code 'n'} is negative, or greater than
1195     * {@code srcStr.length()}, this exception shall throw.
1196     */
1197    public static int nthFromEnd_CI(String srcStr, int n, char c)
1198    {
1199        NException.check(n, srcStr);
1200
1201        LV l = new LV(srcStr, 0, -1);
1202
1203        c = Character.toLowerCase(c);
1204
1205        for (int i=(l.end-1); i >= l.start; i--)
1206            if (c == Character.toLowerCase(srcStr.charAt(i))) if (--n == 0) return i;
1207
1208        return -1;
1209    }
1210
1211    /**
1212     * Search for the <B STYLE='color: red'>nth</B> occurence of substring {@code 'cmpStr'}, but
1213     * start the search with the <I>last character of the String and work
1214     * <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into {@code 'srcStr'}
1215     * where the match occured.
1216     * 
1217     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
1218     * 
1219     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1220     * for the specified matches, and an index-pointer as an integer will be returned.
1221     * 
1222     * @param n This is the number of matches to skip when searching for substring {@code 'cmpStr'}
1223     * before returning an answer.
1224     * 
1225     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
1226     * {@code String 'srcStr'}.
1227     * 
1228     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1229     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> from the end of
1230     * {@code 'srcStr'}</I>
1231     * 
1232     * @throws NException If the value of {@code 'n'} is negative, or greater than
1233     * {@code srcStr.length()}, this exception shall throw.
1234     */
1235    public static int nthFromEnd_CI(String srcStr, int n, String cmpStr)
1236    {
1237        NException.check(n, srcStr);
1238
1239        LV  l           = new LV(srcStr, 0, -1, cmpStr.length());
1240        int cmpStrLen   = cmpStr.length();
1241
1242        for (int i=(l.end-1); i >= l.start; i--)
1243            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) if (--n == 0) return i;
1244
1245        return -1;
1246    }
1247
1248    /**
1249     * Search for the <B STYLE='color: red'>nth</B> occurence of character {@code 'c'}, but
1250     * start the search with the <I>last character of the String and work
1251     * <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into {@code 'srcStr'}
1252     * where the match occured.
1253     * 
1254     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
1255     * 
1256     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
1257     * 
1258     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1259     * for the specified matches, and an index-pointer as an integer will be returned.
1260     * 
1261     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
1262     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
1263     * 
1264     * @param n This is the number of matches to skip when searching for character {@code 'c'}
1265     * before returning an answer.
1266     * 
1267     * @param c This is the character that will be 'searched-for' in input-parameter
1268     * {@code String 'srcStr'}.
1269     * 
1270     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1271     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> from the end of
1272     * {@code 'srcStr'}</I>
1273     * 
1274     * @throws StringIndexOutOfBoundsException
1275     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
1276     * 
1277     * @throws NException If the value of {@code 'n'} is negative, or greater than
1278     * {@code srcStr.length()}, this exception shall throw.
1279     */
1280    public static int nthFromEnd(String srcStr, int sPos, int ePos, int n, char c)
1281    {
1282        NException.check(n, srcStr);
1283
1284        LV l = new LV(srcStr, sPos, ePos);
1285
1286        for (int i=(l.end-1); i >= l.start; i--)
1287            if (c == srcStr.charAt(i)) if (--n == 0) return i;
1288
1289        return -1;
1290    }
1291
1292    /**
1293     * Search for the <B STYLE='color: red'>nth</B> occurence of substring {@code 'cmpStr'}, but
1294     * start the search with the <I>last character of the String and work
1295     * <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into {@code 'srcStr'}
1296     * where the match occured.
1297     * 
1298     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
1299     * 
1300     * <EMBED CLASS='external-html' DATA-FILE-ID=STR_SUBSECT>
1301     * 
1302     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1303     * for the specified matches, and an index-pointer as an integer will be returned.
1304     * 
1305     * @param sPos <EMBED CLASS='external-html' DATA-FILE-ID=SPOSSTR>
1306     * @param ePos <EMBED CLASS='external-html' DATA-FILE-ID=EPOSSTR>
1307     * 
1308     * @param n This is the number of matches to skip when searching for substring {@code 'cmpStr'}
1309     * before returning an answer.
1310     * 
1311     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
1312     * {@code String 'srcStr'}.
1313     * 
1314     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1315     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> from the end of
1316     * {@code 'srcStr'}</I>
1317     * 
1318     * @throws StringIndexOutOfBoundsException
1319     * <EMBED CLASS='external-html' DATA-FILE-ID=SIOOB_EX>
1320     * 
1321     * @throws NException If the value of {@code 'n'} is negative, or greater than
1322     * {@code srcStr.length()}, this exception shall throw.
1323     */
1324    public static int nthFromEnd(String srcStr, int sPos, int ePos, int n, String cmpStr)
1325    {
1326        NException.check(n, srcStr);
1327
1328        LV  l           = new LV(srcStr, sPos, ePos, cmpStr.length());
1329        int cmpStrLen   = cmpStr.length();
1330
1331        for (int i=(l.end-1); i >= l.start; i--)
1332            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) if (--n == 0) return i;
1333
1334        return -1;
1335    }
1336
1337    /**
1338     * Search for the <B STYLE='color: red'>nth</B> occurence of character {@code 'c'}, but
1339     * start the search with the <I>last character of the String and work
1340     * <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into {@code 'srcStr'}
1341     * where the match occured.
1342     * 
1343     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
1344     * 
1345     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1346     * for the specified matches, and an index-pointer as an integer will be returned.
1347     * 
1348     * @param n This is the number of matches to skip when searching for character {@code 'c'}
1349     * before returning an answer.
1350     * 
1351     * @param c This is the character that will be 'searched-for' in input-parameter
1352     * {@code String 'srcStr'}.
1353     * 
1354     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1355     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> from the end of
1356     * {@code 'srcStr'}</I>
1357     * 
1358     * @throws NException If the value of {@code 'n'} is negative, or greater than
1359     * {@code srcStr.length()}, this exception shall throw.
1360     */
1361    public static int nthFromEnd(String srcStr, int n, char c)
1362    {
1363        NException.check(n, srcStr);
1364
1365        LV l = new LV(srcStr, 0, -1);
1366
1367        for (int i=(l.end-1); i >= l.start; i--)
1368            if (c == srcStr.charAt(i)) if (--n == 0) return i;
1369
1370        return -1;
1371    }
1372
1373    /**
1374     * Search for the <B STYLE='color: red'>nth</B> occurence of substring {@code 'cmpStr'}, but
1375     * start the search with the <I>last character of the String and work
1376     * <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into {@code 'srcStr'}
1377     * where the match occured.
1378     * 
1379     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
1380     * 
1381     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1382     * for the specified matches, and an index-pointer as an integer will be returned.
1383     * 
1384     * @param n This is the number of matches to skip when searching for substring {@code 'cmpStr'}
1385     * before returning an answer.
1386     * 
1387     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
1388     * {@code String 'srcStr'}.
1389     * 
1390     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1391     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> from the end of
1392     * {@code 'srcStr'}</I>
1393     * 
1394     * @throws NException If the value of {@code 'n'} is negative, or greater than
1395     * {@code srcStr.length()}, this exception shall throw.
1396     */
1397    public static int nthFromEnd(String srcStr, int n, String cmpStr)
1398    {
1399        NException.check(n, srcStr);
1400
1401        LV  l           = new LV(srcStr, 0, -1, cmpStr.length());
1402        int cmpStrLen   = cmpStr.length();
1403
1404        for (int i=(l.end-1); i >= l.start; i--)
1405            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) if (--n == 0) return i;
1406
1407        return -1;
1408    }
1409
1410    /**
1411     * Search for the <B STYLE='color: red'>first</B> occurence of character {@code 'c'}
1412     * , but <I>search <B STYLE='color: red'>left</B> beginning at {@code 'srcStr'} position
1413     * {@code 'fromIndex'}</I>.
1414
1415     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
1416     * match occured.
1417     * 
1418     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
1419     * 
1420     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1421     * for the specified matches, and an index-pointer as an integer will be returned.
1422     * 
1423     * @param fromIndex This is the right-most index-position in {@code 'srcStr'} (*INCLUSIVE*)
1424     * from where the search shall start.
1425     * 
1426     * @param c This is the character that will be 'searched-for' in input-parameter
1427     * {@code String 'srcStr'}.
1428     * 
1429     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
1430     * sub-string match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B>
1431     * in {@code 'srcStr'} from position {@code 'fromIndex'}</I>
1432     */
1433    public static int left_CI(String srcStr, int fromIndex, char c)
1434    {
1435        LV l = new LV(srcStr, 0, fromIndex);
1436
1437        c = Character.toLowerCase(c);
1438
1439        for (int i=l.end; i >= 0; i--)
1440            if (c == Character.toLowerCase(srcStr.charAt(i))) return i;
1441
1442        return -1;
1443    }
1444
1445    /**
1446     * Search for the <B STYLE='color: red'>first</B> occurence of substring {@code 'cmpStr'}
1447     * , but <I>search <B STYLE='color: red'>left</B> beginning at {@code 'srcStr'} position
1448     * {@code 'fromIndex'}</I>.
1449
1450     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
1451     * match occured.
1452     * 
1453     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
1454     * 
1455     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1456     * for the specified matches, and an index-pointer as an integer will be returned.
1457     * 
1458     * @param fromIndex This is the right-most index-position in {@code 'srcStr'} (*INCLUSIVE*)
1459     * from where the search shall start.
1460     * 
1461     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
1462     * {@code String 'srcStr'}.
1463     * 
1464     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
1465     * sub-string match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B>
1466     * in {@code 'srcStr'} from position {@code 'fromIndex'}</I>
1467     */
1468    public static int left_CI(String srcStr, int fromIndex, String cmpStr)
1469    {
1470        LV  l           = new LV(srcStr, 0, fromIndex, cmpStr.length());
1471        int cmpStrLen   = cmpStr.length();
1472
1473        for (int i=l.end; i >= 0; i--)
1474            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) return i;
1475
1476        return -1;
1477    }
1478
1479    /**
1480     * Search for the <B STYLE='color: red'>first</B> occurence of character {@code 'c'}
1481     * , but <I>search <B STYLE='color: red'>left</B> beginning at {@code 'srcStr'} position
1482     * {@code 'fromIndex'}</I>.
1483
1484     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
1485     * match occured.
1486     * 
1487     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
1488     * 
1489     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1490     * for the specified matches, and an index-pointer as an integer will be returned.
1491     * 
1492     * @param fromIndex This is the right-most index-position in {@code 'srcStr'} (*INCLUSIVE*)
1493     * from where the search shall start.
1494     * 
1495     * @param c This is the character that will be 'searched-for' in input-parameter
1496     * {@code String 'srcStr'}.
1497     * 
1498     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
1499     * sub-string match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B>
1500     * in {@code 'srcStr'} from position {@code 'fromIndex'}</I>
1501     */
1502    public static int left(String srcStr, int fromIndex, char c)
1503    {
1504        LV l = new LV(srcStr, 0, fromIndex);
1505
1506        for (int i=l.end; i >= 0; i--)
1507            if (c == srcStr.charAt(i)) return i;
1508
1509        return -1;
1510    }
1511
1512    /**
1513     * Search for the <B STYLE='color: red'>first</B> occurence of substring {@code 'cmpStr'}
1514     * , but <I>search <B STYLE='color: red'>left</B> beginning at {@code 'srcStr'} position
1515     * {@code 'fromIndex'}</I>.
1516
1517     * in {@code 'srcStr'}, and return the integer index-location into {@code 'srcStr'} where the
1518     * match occured.
1519     * 
1520     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
1521     * 
1522     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1523     * for the specified matches, and an index-pointer as an integer will be returned.
1524     * 
1525     * @param fromIndex This is the right-most index-position in {@code 'srcStr'} (*INCLUSIVE*)
1526     * from where the search shall start.
1527     * 
1528     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
1529     * {@code String 'srcStr'}.
1530     * 
1531     * @return The {@code String} index of the <B STYLE='color: red'>first</B> identified
1532     * sub-string match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B>
1533     * in {@code 'srcStr'} from position {@code 'fromIndex'}</I>
1534     */
1535    public static int left(String srcStr, int fromIndex, String cmpStr)
1536    {
1537        LV  l           = new LV(srcStr, 0, fromIndex, cmpStr.length());
1538        int cmpStrLen   = cmpStr.length();
1539
1540        for (int i=l.end; i >= 0; i--)
1541            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) return i;
1542
1543        return -1;
1544    }
1545
1546    /**
1547     * Search for the <B STYLE='color: red'>nth</B> occurence of character {@code 'c'} in
1548     * {@code 'srcStr'}, but <I>begin the search at index-position {@code 'fromIndex'}
1549     * and work <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into
1550     * {@code 'srcStr'} where the match occured.
1551     * 
1552     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
1553     * 
1554     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1555     * for the specified matches, and an index-pointer as an integer will be returned.
1556     * 
1557     * @param fromIndex This is the right-most index-position in {@code 'srcStr'} (*INCLUSIVE*)
1558     * from where the search shall start.
1559     * 
1560     * @param n This is the number of matches to skip when searching for character {@code 'c'}
1561     * before returning an answer.
1562     * 
1563     * @param c This is the character that will be 'searched-for' in input-parameter
1564     * {@code String 'srcStr'}.
1565     * 
1566     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1567     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> in {@code 'srcStr'}
1568     * from position {@code 'fromIndex'}</I>
1569     * 
1570     * @throws NException If the value of {@code 'n'} is negative, or greater than
1571     * {@code srcStr.length()}, this exception shall throw.
1572     */
1573    public static int nthLeft_CI(String srcStr, int fromIndex, int n, char c)
1574    {
1575        NException.check(n, srcStr);
1576
1577        LV l = new LV(srcStr, 0, fromIndex);
1578
1579        c = Character.toLowerCase(c);
1580
1581        for (int i=l.end; i >= 0; i--)
1582            if (c == Character.toLowerCase(srcStr.charAt(i))) if (--n == 0) return i;
1583
1584        return -1;
1585    }
1586
1587    /**
1588     * Search for the <B STYLE='color: red'>nth</B> occurence of substring {@code 'cmpStr'} in
1589     * {@code 'srcStr'}, but <I>begin the search at index-position {@code 'fromIndex'}
1590     * and work <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into
1591     * {@code 'srcStr'} where the match occured.
1592     * 
1593     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are not **</B> case-sensitive
1594     * 
1595     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1596     * for the specified matches, and an index-pointer as an integer will be returned.
1597     * 
1598     * @param fromIndex This is the right-most index-position in {@code 'srcStr'} (*INCLUSIVE*)
1599     * from where the search shall start.
1600     * 
1601     * @param n This is the number of matches to skip when searching for substring {@code 'cmpStr'}
1602     * before returning an answer.
1603     * 
1604     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
1605     * {@code String 'srcStr'}.
1606     * 
1607     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1608     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> in {@code 'srcStr'}
1609     * from position {@code 'fromIndex'}</I>
1610     * 
1611     * @throws NException If the value of {@code 'n'} is negative, or greater than
1612     * {@code srcStr.length()}, this exception shall throw.
1613     */
1614    public static int nthLeft_CI(String srcStr, int fromIndex, int n, String cmpStr)
1615    {
1616        NException.check(n, srcStr);
1617
1618        LV  l           = new LV(srcStr, 0, fromIndex, cmpStr.length());
1619        int cmpStrLen   = cmpStr.length();
1620
1621        for (int i=l.end; i >= 0; i--)
1622            if (srcStr.regionMatches(true, i, cmpStr, 0, cmpStrLen)) if (--n == 0) return i;
1623
1624        return -1;
1625    }
1626
1627    /**
1628     * Search for the <B STYLE='color: red'>nth</B> occurence of character {@code 'c'} in
1629     * {@code 'srcStr'}, but <I>begin the search at index-position {@code 'fromIndex'}
1630     * and work <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into
1631     * {@code 'srcStr'} where the match occured.
1632     * 
1633     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
1634     * 
1635     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1636     * for the specified matches, and an index-pointer as an integer will be returned.
1637     * 
1638     * @param fromIndex This is the right-most index-position in {@code 'srcStr'} (*INCLUSIVE*)
1639     * from where the search shall start.
1640     * 
1641     * @param n This is the number of matches to skip when searching for character {@code 'c'}
1642     * before returning an answer.
1643     * 
1644     * @param c This is the character that will be 'searched-for' in input-parameter
1645     * {@code String 'srcStr'}.
1646     * 
1647     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1648     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> in {@code 'srcStr'}
1649     * from position {@code 'fromIndex'}</I>
1650     * 
1651     * @throws NException If the value of {@code 'n'} is negative, or greater than
1652     * {@code srcStr.length()}, this exception shall throw.
1653     */
1654    public static int nthLeft(String srcStr, int fromIndex, int n, char c)
1655    {
1656        NException.check(n, srcStr);
1657
1658        LV l = new LV(srcStr, 0, fromIndex);
1659
1660        for (int i=l.end; i >= 0; i--)
1661            if (c == srcStr.charAt(i)) if (--n == 0) return i;
1662
1663        return -1;
1664    }
1665
1666    /**
1667     * Search for the <B STYLE='color: red'>nth</B> occurence of substring {@code 'cmpStr'} in
1668     * {@code 'srcStr'}, but <I>begin the search at index-position {@code 'fromIndex'}
1669     * and work <B STYLE='color: red'>left</B>.</I>  Return the integer index-location into
1670     * {@code 'srcStr'} where the match occured.
1671     * 
1672     * <BR /><BR />The comparisons performed <B STYLE='color: red'>** are **</B> case-sensitive
1673     * 
1674     * @param srcStr This may be any {@code java.lang.String}.  It's contents will be searched
1675     * for the specified matches, and an index-pointer as an integer will be returned.
1676     * 
1677     * @param fromIndex This is the right-most index-position in {@code 'srcStr'} (*INCLUSIVE*)
1678     * from where the search shall start.
1679     * 
1680     * @param n This is the number of matches to skip when searching for substring {@code 'cmpStr'}
1681     * before returning an answer.
1682     * 
1683     * @param cmpStr This is the sub-string that will be 'searched-for' in input parameter
1684     * {@code String 'srcStr'}.
1685     * 
1686     * @return The {@code String} index of the <B STYLE='color: red'>nth</B> identified sub-string
1687     * match in {@code 'srcStr'}, <I>counting <B STYLE='color: red'>left</B> in {@code 'srcStr'}
1688     * from position {@code 'fromIndex'}</I>
1689     * 
1690     * @throws NException If the value of {@code 'n'} is negative, or greater than
1691     * {@code srcStr.length()}, this exception shall throw.
1692     */
1693    public static int nthLeft(String srcStr, int fromIndex, int n, String cmpStr)
1694    {
1695        NException.check(n, srcStr);
1696
1697        LV  l           = new LV(srcStr, 0, fromIndex, cmpStr.length());
1698        int cmpStrLen   = cmpStr.length();
1699
1700        for (int i=l.end; i >= 0; i--)
1701            if (srcStr.regionMatches(i, cmpStr, 0, cmpStrLen)) if (--n == 0) return i;
1702
1703        return -1;
1704    }
1705
1706}