KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jodd > util > StringUtil


1 // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
2

3 package jodd.util;
4
5 import jodd.typeconverter.StringArrayConverter;
6
7 import java.io.UnsupportedEncodingException JavaDoc;
8
9
10 /**
11  * Various String utilities.
12  */

13 public class StringUtil {
14
15     public static final String JavaDoc WHITESPACE = " \n\r\f\t";
16     public static final String JavaDoc EMPTY_STRING = "";
17
18     // ---------------------------------------------------------------- replace
19

20     /**
21      * Replaces the occurrences of a certain pattern in a string with a
22      * replacement string. This is the fastest replace function known to author.
23      *
24      * @param s string to be inspected
25      * @param sub string pattern to be replaced
26      * @param with string that should go where the pattern was
27      */

28     public static String JavaDoc replace(String JavaDoc s, String JavaDoc sub, String JavaDoc with) {
29         int c = 0;
30         int i = s.indexOf(sub, c);
31         if (i == -1) {
32             return s;
33         }
34         int sLen = s.length();
35         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(sLen + with.length());
36         do {
37              buf.append(s.substring(c,i));
38              buf.append(with);
39              c = i + sub.length();
40          } while ((i = s.indexOf(sub, c)) != -1);
41          if (c < sLen) {
42              buf.append(s.substring(c, sLen));
43          }
44          return buf.toString();
45     }
46
47     /**
48      * Replaces all occurrences of a character in a string.
49      *
50      * @param s input string
51      * @param sub character to replace
52      * @param with character to replace with
53      */

54     public static String JavaDoc replace(String JavaDoc s, char sub, char with) {
55         char[] str = s.toCharArray();
56         for (int i = 0; i < str.length; i++) {
57             if (str[i] == sub) {
58                 str[i] = with;
59             }
60         }
61         return new String JavaDoc(str);
62     }
63
64     /**
65      * Replaces the very first occurrence of a substring with supplied string.
66      *
67      * @param s source string
68      * @param sub substring to replace
69      * @param with substring to replace with
70      */

71     public static String JavaDoc replaceFirst(String JavaDoc s, String JavaDoc sub, String JavaDoc with) {
72         int i = s.indexOf(sub);
73         if (i == -1) {
74             return s;
75         }
76         return s.substring(0, i) + with + s.substring(i + sub.length());
77     }
78
79     /**
80      * Replaces the very first occurrence of a character in a string.
81      *
82      * @param s string
83      * @param sub char to replace
84      * @param with char to replace with
85      */

86     public static String JavaDoc replaceFirst(String JavaDoc s, char sub, char with) {
87         char[] str = s.toCharArray();
88         for (int i = 0; i < str.length; i++) {
89             if (str[i] == sub) {
90                 str[i] = with;
91                 break;
92             }
93         }
94         return new String JavaDoc(str);
95     }
96
97     /**
98      * Replaces the very last occurrence of a substring with supplied string.
99      *
100      * @param s source string
101      * @param sub substring to replace
102      * @param with substring to replace with
103      */

104     public static String JavaDoc replaceLast(String JavaDoc s, String JavaDoc sub, String JavaDoc with) {
105         int i = s.lastIndexOf(sub);
106         if (i == -1) {
107             return s;
108         }
109         return s.substring(0, i) + with + s.substring(i + sub.length());
110     }
111
112     /**
113      * Replaces the very last occurrence of a character in a string.
114      *
115      * @param s string
116      * @param sub char to replace
117      * @param with char to replace with
118      */

119     public static String JavaDoc replaceLast(String JavaDoc s, char sub, char with) {
120         char[] str = s.toCharArray();
121         for (int i = str.length - 1; i >= 0; i--) {
122             if (str[i] == sub) {
123                 str[i] = with;
124                 break;
125             }
126         }
127         return new String JavaDoc(str);
128     }
129
130     // ---------------------------------------------------------------- remove
131

132     /**
133      * Removes all substring occurrences from the string.
134      *
135      * @param s source string
136      * @param sub substring to remove
137      */

138     public static String JavaDoc remove(String JavaDoc s, String JavaDoc sub) {
139         int c = 0;
140         int sublen = sub.length();
141         if (sublen == 0) {
142             return s;
143         }
144         int i = s.indexOf(sub, c);
145         if (i == -1) {
146             return s;
147         }
148         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(s.length());
149         do {
150              buf.append(s.substring(c, i));
151              c = i + sublen;
152          } while ((i = s.indexOf(sub, c)) != -1);
153          if (c < s.length()) {
154              buf.append(s.substring(c, s.length()));
155          }
156          return buf.toString();
157     }
158
159     /**
160      * Removes all characters contained in provided string.
161      *
162      * @param src source string
163      * @param chars string containing characters to remove
164      */

165     public static String JavaDoc removeChars(String JavaDoc src, String JavaDoc chars) {
166         int i = src.length();
167         StringBuffer JavaDoc stringbuffer = new StringBuffer JavaDoc(i);
168         for (int j = 0; j < i; j++) {
169             char c = src.charAt(j);
170             if (chars.indexOf(c) == -1) {
171                 stringbuffer.append(c);
172             }
173         }
174         return stringbuffer.toString();
175     }
176
177
178     /**
179      * Removes set of characters from string.
180      *
181      * @param src string
182      * @param chars character to remove
183      */

184     public static String JavaDoc removeChars(String JavaDoc src, char[] chars) {
185         int i = src.length();
186         StringBuffer JavaDoc stringbuffer = new StringBuffer JavaDoc(i);
187         mainloop:
188         for (int j = 0; j < i; j++) {
189             char c = src.charAt(j);
190             for (int k = 0; k < chars.length; k++) {
191                 if (c == chars[k]) {
192                     continue mainloop;
193                 }
194             }
195             stringbuffer.append(c);
196         }
197         return stringbuffer.toString();
198     }
199
200     /**
201      * Removes a single character from string.
202      *
203      * @param src source string
204      * @param chars character to remove
205      */

206     public static String JavaDoc remove(String JavaDoc src, char chars) {
207         int i = src.length();
208         StringBuffer JavaDoc stringbuffer = new StringBuffer JavaDoc(i);
209         for (int j = 0; j < i; j++) {
210             char c = src.charAt(j);
211             if (c == chars) {
212                 continue;
213             }
214             stringbuffer.append(c);
215         }
216         return stringbuffer.toString();
217     }
218
219     // ---------------------------------------------------------------- miscellaneous
220

221     /**
222      * Compares 2 strings. If one of the strings is <code>null</code>, <code>false</code> is returned. if
223      * both string are <code>null</code>, <code>true</code> is returned.
224      *
225      * @param s1 first string to compare
226      * @param s2 second string
227      *
228      * @return <code>true</code> if strings are equal, otherwise <code>false</code>
229      */

230     public static boolean equals(String JavaDoc s1, String JavaDoc s2) {
231         return ObjectUtil.equals(s1, s2);
232     }
233
234     /**
235      * Determines if a string is empty (<code>null</code> or empty).
236      */

237     public static boolean isEmpty(String JavaDoc string) {
238         return ((string == null) || (string.length() == 0));
239     }
240
241     /**
242      * Determines if a string is blank (<code>null</code> or trimmed empty).,
243      */

244     public static boolean isBlank(String JavaDoc string) {
245         return ((string == null) || (string.trim().length() == 0));
246     }
247
248     /**
249      * Determines if a string is not empty.
250      */

251     public static boolean isNotEmpty(String JavaDoc string) {
252         return string != null && string.length() > 0;
253     }
254
255
256     /**
257      * Converts safely an object to a string. If object is <code>null</code> it will be
258      * not converted.
259      */

260     public static String JavaDoc toString(Object JavaDoc obj) {
261         if (obj == null) {
262             return null;
263         }
264         return obj.toString();
265     }
266
267     /**
268      * Converts safely an object to a string. If object is <code>null</code> a empty
269      * string is returned.
270      */

271     public static String JavaDoc toNotNullString(Object JavaDoc obj) {
272         if (obj == null) {
273             return EMPTY_STRING;
274         }
275         return obj.toString();
276     }
277
278     /**
279      * Converts an object to a String Array.
280      */

281     public static String JavaDoc[] toStringArray(Object JavaDoc obj) {
282         return StringArrayConverter.valueOf(obj);
283     }
284
285
286     // ---------------------------------------------------------------- captialize
287

288     /**
289      * Capitalizes a string, changing the first letter to
290      * upper case. No other letters are changed.
291      *
292      * @param str string to capitalize, may be null
293      * @see #uncapitalize(String)
294      */

295     public static String JavaDoc capitalize(String JavaDoc str) {
296         return changeFirstCharacterCase(true, str);
297     }
298
299     /**
300      * Uncapitalizes a <code>String</code>, changing the first letter to
301      * lower case. No other letters are changed.
302      *
303      * @param str the String to uncapitalize, may be null
304      * @return the uncapitalized String, <code>null</code> if null
305      * @see #capitalize(String)
306      */

307     public static String JavaDoc uncapitalize(String JavaDoc str) {
308         return changeFirstCharacterCase(false, str);
309     }
310
311     /**
312      * Internal method for changing the first character case. It is significantly
313      * faster using StringBuffers then just simply Strings.
314      * @param capitalize
315      * @param str
316      */

317     private static String JavaDoc changeFirstCharacterCase(boolean capitalize, String JavaDoc str) {
318         int strLen = str.length();
319         if (strLen == 0) {
320             return str;
321         }
322         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(strLen);
323         if (capitalize) {
324             buf.append(Character.toUpperCase(str.charAt(0)));
325         } else {
326             buf.append(Character.toLowerCase(str.charAt(0)));
327         }
328         buf.append(str.substring(1));
329         return buf.toString();
330     }
331
332
333     // ---------------------------------------------------------------- truncate
334

335
336     /**
337      * Sets the maximum length of the string. Longer strings will be simply truncaten.
338      */

339     public static String JavaDoc truncate(String JavaDoc string, int length) {
340         if (string.length() > length) {
341             string = string.substring(0, length);
342         }
343         return string;
344     }
345
346     // ---------------------------------------------------------------- split
347

348     /**
349      * Splits a string in several parts (tokens) that are separated by delimiter.
350      * Delimiter is <b>always</b> surrounded by two strings! If there is no
351      * content between two delimiters, empty string will be returned for that
352      * token. Therefore, the length of the returned array will always be:
353      * #delimiters + 1.
354      * <p>
355      * Method is much, much faster then regexp <code>String.split()</code>,
356      * and a bit faster then <code>StringTokenizer</code>.
357      *
358      * @param src string to split
359      * @param delimeter split delimiter
360      *
361      * @return array of split strings
362      */

363     public static String JavaDoc[] split(String JavaDoc src, String JavaDoc delimeter) {
364         int maxparts = (src.length() / delimeter.length()) + 2; // one more for the last
365
int[] positions = new int[maxparts];
366         int dellen = delimeter.length();
367
368         int i, j = 0;
369         int count = 0;
370         positions[0] = - dellen;
371         while ((i = src.indexOf(delimeter, j)) != -1) {
372             count++;
373             positions[count] = i;
374             j = i + dellen;
375         }
376         count++;
377         positions[count] = src.length();
378
379         String JavaDoc[] result = new String JavaDoc[count];
380
381         for (i = 0; i < count; i++) {
382             result[i] = src.substring(positions[i] + dellen, positions[i + 1]);
383         }
384         return result;
385     }
386
387     /**
388      * Splits a string in several parts (tokens) that are separated by delimiter
389      * characters. Delimiter may contains any number of character, and it is
390      * always surrounded by two strings.
391      *
392      * @param src source to examine
393      * @param d string with delimiter characters
394      *
395      * @return array of tokens
396      */

397     public static String JavaDoc[] splitc(String JavaDoc src, String JavaDoc d) {
398         if ((d.length() == 0) || (src.length() == 0) ) {
399             return new String JavaDoc[] {src};
400         }
401         char[] delimiters = d.toCharArray();
402         char[] srcc = src.toCharArray();
403
404         int maxparts = srcc.length + 1;
405         int[] start = new int[maxparts];
406         int[] end = new int[maxparts];
407
408         int count = 0;
409
410         start[0] = 0;
411         int s = 0, e;
412         if (CharUtil.equalsOne(srcc[0], delimiters) == true) { // string starts with delimiter
413
end[0] = 0;
414             count++;
415             s = CharUtil.findFirstDiff(srcc, 1, delimiters);
416             if (s == -1) { // nothing after delimiters
417
return new String JavaDoc[] {EMPTY_STRING, EMPTY_STRING};
418             }
419             start[1] = s; // new start
420
}
421         while (true) {
422             // find new end
423
e = CharUtil.findFirstEqual(srcc, s, delimiters);
424             if (e == -1) {
425                 end[count] = srcc.length;
426                 break;
427             }
428             end[count] = e;
429
430             // find new start
431
count++;
432             s = CharUtil.findFirstDiff(srcc, e, delimiters);
433             if (s == -1) {
434                 start[count] = end[count] = srcc.length;
435                 break;
436             }
437             start[count] = s;
438         }
439         count++;
440         String JavaDoc[] result = new String JavaDoc[count];
441         for (int i = 0; i < count; i++) {
442             result[i] = src.substring(start[i], end[i]);
443         }
444         return result;
445     }
446
447     /**
448      * Splits a string in several parts (tokens) that are separated by single delimiter
449      * characters. Delimiter may contains any number of character, and it is
450      * always surrounded by two strings.
451      *
452      * @param src source to examine
453      * @param delimiter delimiter character
454      *
455      * @return array of tokens
456      */

457     public static String JavaDoc[] splitc(String JavaDoc src, char delimiter) {
458         char[] srcc = src.toCharArray();
459
460         int maxparts = srcc.length + 1;
461         int[] start = new int[maxparts];
462         int[] end = new int[maxparts];
463
464         int count = 0;
465
466         start[0] = 0;
467         int s = 0, e;
468         if (srcc[0] == delimiter) { // string starts with delimiter
469
end[0] = 0;
470             count++;
471             s = CharUtil.findFirstDiff(srcc, 1, delimiter);
472             if (s == -1) { // nothing after delimiters
473
return new String JavaDoc[] {EMPTY_STRING, EMPTY_STRING};
474             }
475             start[1] = s; // new start
476
}
477         while (true) {
478             // find new end
479
e = CharUtil.findFirstEqual(srcc, s, delimiter);
480             if (e == -1) {
481                 end[count] = srcc.length;
482                 break;
483             }
484             end[count] = e;
485
486             // find new start
487
count++;
488             s = CharUtil.findFirstDiff(srcc, e, delimiter);
489             if (s == -1) {
490                 start[count] = end[count] = srcc.length;
491                 break;
492             }
493             start[count] = s;
494         }
495         count++;
496         String JavaDoc[] result = new String JavaDoc[count];
497         for (int i = 0; i < count; i++) {
498             result[i] = src.substring(start[i], end[i]);
499         }
500         return result;
501     }
502
503
504     // ---------------------------------------------------------------- indexof and ignore cases
505

506     /**
507      * Finds first occurence of a substring in the given source but within limited range [start, end).
508      * It is fastest possible code, but still original <code>String.indexOf(String, int)</code>
509      * is much faster (since it uses char[] value directly) and should be used when no range is needed.
510      *
511      * @param src source string for examination
512      * @param sub substring to find
513      * @param startIndex starting index
514      * @param endIndex ending index
515      * @return index of founded substring or -1 if substring not found
516      */

517     public static int indexOf(String JavaDoc src, String JavaDoc sub, int startIndex, int endIndex) {
518         int sublen = sub.length();
519         if (sublen == 0) {
520             return startIndex;
521         }
522         int total = endIndex - sublen + 1;
523         char c = sub.charAt(0);
524     mainloop:
525         for (int i = startIndex; i < total; i++) {
526             if (src.charAt(i) != c) {
527                 continue;
528             }
529             int j = 1;
530             int k = i + 1;
531             while (j < sublen) {
532                 if (sub.charAt(j) != src.charAt(k)) {
533                     continue mainloop;
534                 }
535                 j++; k++;
536             }
537             return i;
538         }
539         return -1;
540     }
541
542     /**
543      * Finds the first occurence of a character in the given source but within limited range (start, end].
544      */

545     public static int indexOf(String JavaDoc src, char c, int startIndex, int endIndex) {
546         for (int i = startIndex; i < endIndex; i++) {
547             if (src.charAt(i) == c) {
548                 return i;
549             }
550         }
551         return -1;
552     }
553
554
555
556     /**
557      * Finds first index of a substring in the given source string with ignored case.
558      *
559      * @param src source string for examination
560      * @param subS substring to find
561      *
562      * @return index of founded substring or -1 if substring is not found
563      * @see #indexOfIgnoreCase(String, String, int)
564      */

565     public static int indexOfIgnoreCase(String JavaDoc src, String JavaDoc subS) {
566         return indexOfIgnoreCase(src, subS, 0, src.length());
567     }
568
569     /**
570      * Finds first index of a substring in the given source string with ignored
571      * case. This seems to be the fastest way doing this, with common string
572      * length and content (of course, with no use of Boyer-Mayer type of
573      * algorithms). Other implementations are slower: getting char array first,
574      * lower casing the source string, using String.regionMatch etc.
575      *
576      * @param src source string for examination
577      * @param subS substring to find
578      * @param startIndex starting index from where search begins
579      *
580      * @return index of founded substring or -1 if substring is not found
581      */

582     public static int indexOfIgnoreCase(String JavaDoc src, String JavaDoc subS, int startIndex) {
583         return indexOfIgnoreCase(src, subS, startIndex, src.length());
584     }
585     /**
586      * Finds first index of a substring in the given source string and range with
587      * ignored case.
588      *
589      * @param src source string for examination
590      * @param sub substring to find
591      * @param startIndex starting index from where search begins
592      * @param endIndex endint index
593      * @return index of founded substring or -1 if substring is not found
594      * @see #indexOfIgnoreCase(String, String, int)
595      */

596     public static int indexOfIgnoreCase(String JavaDoc src, String JavaDoc sub, int startIndex, int endIndex) {
597         int sublen = sub.length();
598         if (sublen == 0) {
599             return startIndex;
600         }
601         sub = sub.toLowerCase();
602         int total = endIndex - sublen + 1;
603         char c = sub.charAt(0);
604     mainloop:
605         for (int i = startIndex; i < total; i++) {
606             if (Character.toLowerCase(src.charAt(i)) != c) {
607                 continue;
608             }
609             int j = 1;
610             int k = i + 1;
611             while (j < sublen) {
612                 char source = Character.toLowerCase(src.charAt(k));
613                 if (sub.charAt(j) != source) {
614                     continue mainloop;
615                 }
616                 j++; k++;
617             }
618             return i;
619         }
620         return -1;
621     }
622
623
624     /**
625      * Finds last index of a substring in the given source string with ignored
626      * case.
627      *
628      * @param s source string
629      * @param subS substring to find
630      *
631      * @return last index of founded substring or -1 if substring is not found
632      * @see #indexOfIgnoreCase(String, String, int)
633      * @see #lastIndexOfIgnoreCase(String, String, int)
634      */

635     public static int lastIndexOfIgnoreCase(String JavaDoc s, String JavaDoc subS) {
636         return lastIndexOfIgnoreCase(s, subS, s.length(), 0);
637     }
638
639     /**
640      * Finds last index of a substring in the given source string with ignored
641      * case.
642      *
643      * @param src source string for examination
644      * @param subS substring to find
645      * @param startIndex starting index from where search begins
646      *
647      * @return last index of founded substring or -1 if substring is not found
648      * @see #indexOfIgnoreCase(String, String, int)
649      */

650     public static int lastIndexOfIgnoreCase(String JavaDoc src, String JavaDoc subS, int startIndex) {
651         return lastIndexOfIgnoreCase(src, subS, startIndex, 0);
652     }
653     /**
654      * Finds last index of a substring in the given source string with ignored
655      * case in specified range.
656      *
657      * @param src source to examine
658      * @param sub substring to find
659      * @param startIndex starting index
660      * @param endIndex end index
661      * @return last index of founded substring or -1 if substring is not found
662      */

663     public static int lastIndexOfIgnoreCase(String JavaDoc src, String JavaDoc sub, int startIndex, int endIndex) {
664         int sublen = sub.length();
665         if (sublen == 0) {
666             return startIndex;
667         }
668         sub = sub.toLowerCase();
669         int total = src.length() - sublen;
670         if (total < 0) {
671             return -1;
672         }
673         if (startIndex >= total) {
674             startIndex = total;
675         }
676         char c = sub.charAt(0);
677     mainloop:
678         for (int i = startIndex; i >= endIndex; i--) {
679             if (Character.toLowerCase(src.charAt(i)) != c) {
680                 continue;
681             }
682             int j = 1;
683             int k = i + 1;
684             while (j < sublen) {
685                 char source = Character.toLowerCase(src.charAt(k));
686                 if (sub.charAt(j) != source) {
687                     continue mainloop;
688                 }
689                 j++; k++;
690             }
691             return i;
692         }
693         return -1;
694     }
695
696     /**
697      * Finds last index of a substring in the given source string in specified range [end, start]
698      * See {@link #indexOf(String, String, int, int)} for details about the speed.
699      *
700      * @param src source to examine
701      * @param sub substring to find
702      * @param startIndex starting index
703      * @param endIndex end index
704      * @return last index of founded substring or -1 if substring is not found
705      */

706     public static int lastIndexOf(String JavaDoc src, String JavaDoc sub, int startIndex, int endIndex) {
707         int sublen = sub.length();
708         if (sublen == 0) {
709             return startIndex;
710         }
711         int total = src.length() - sublen;
712         if (total < 0) {
713             return -1;
714         }
715         if (startIndex >= total) {
716             startIndex = total;
717         }
718         char c = sub.charAt(0);
719     mainloop:
720         for (int i = startIndex; i >= endIndex; i--) {
721             if (src.charAt(i) != c) {
722                 continue;
723             }
724             int j = 1;
725             int k = i + 1;
726             while (j < sublen) {
727                 if (sub.charAt(j) != src.charAt(k)) {
728                     continue mainloop;
729                 }
730                 j++; k++;
731             }
732             return i;
733         }
734         return -1;
735     }
736
737     /**
738      * Finds last index of a character in the given source string in specified range [end, start]
739      */

740     public static int lastIndexOf(String JavaDoc src, char c, int startIndex, int endIndex) {
741         int total = src.length() - 1;
742         if (total < 0) {
743             return -1;
744         }
745         if (startIndex >= total) {
746             startIndex = total;
747         }
748         for (int i = startIndex; i >= endIndex; i--) {
749             if (src.charAt(i) == c) {
750                 return i;
751             }
752         }
753         return -1;
754     }
755
756
757
758     /**
759      * Tests if this string starts with the specified prefix with ignored case.
760      *
761      * @param src source string to test
762      * @param subS starting substring
763      *
764      * @return <code>true</code> if the character sequence represented by the argument is
765      * a prefix of the character sequence represented by this string;
766      * <code>false</code> otherwise.
767      */

768     public static boolean startsWithIgnoreCase(String JavaDoc src, String JavaDoc subS) {
769         return startsWithIgnoreCase(src, subS, 0);
770     }
771
772     /**
773      * Tests if this string starts with the specified prefix with ignored case
774      * and with the specified prefix beginning a specified index.
775      *
776      * @param src source string to test
777      * @param subS starting substring
778      * @param startIndex index from where to test
779      *
780      * @return <code>true</code> if the character sequence represented by the argument is
781      * a prefix of the character sequence represented by this string;
782      * <code>false</code> otherwise.
783      */

784     public static boolean startsWithIgnoreCase(String JavaDoc src, String JavaDoc subS, int startIndex) {
785         String JavaDoc sub = subS.toLowerCase();
786         int sublen = sub.length();
787         if (startIndex + sublen > src.length()) {
788             return false;
789         }
790         int j = 0;
791         int i = startIndex;
792         while (j < sublen) {
793             char source = Character.toLowerCase(src.charAt(i));
794             if (sub.charAt(j) != source) {
795                 return false;
796             }
797             j++; i++;
798         }
799         return true;
800     }
801
802     /**
803      * Tests if this string ends with the specified suffix.
804      *
805      * @param src String to test
806      * @param subS suffix
807      *
808      * @return <code>true</code> if the character sequence represented by the argument is
809      * a suffix of the character sequence represented by this object;
810      * <code>false</code> otherwise.
811      */

812     public static boolean endsWithIgnoreCase(String JavaDoc src, String JavaDoc subS) {
813         String JavaDoc sub = subS.toLowerCase();
814         int sublen = sub.length();
815         int j = 0;
816         int i = src.length() - sublen;
817         if (i < 0) {
818             return false;
819         }
820         while (j < sublen) {
821             char source = Character.toLowerCase(src.charAt(i));
822             if (sub.charAt(j) != source) {
823                 return false;
824             }
825             j++; i++;
826         }
827         return true;
828     }
829
830
831     // ---------------------------------------------------------------- count substrings
832

833     /**
834      * Count substring occurrences in a source string.
835      *
836      * @param source source string
837      * @param sub substring to count
838      * @return number of substring occurrences
839      */

840     public static int count(String JavaDoc source, String JavaDoc sub) {
841         return count(source, sub, 0);
842     }
843     public static int count(String JavaDoc source, String JavaDoc sub, int start) {
844         int count = 0;
845         int j = start;
846         while (true) {
847             int i = source.indexOf(sub, j);
848             if (i == -1) {
849                 break;
850             }
851             count++;
852             j = i + sub.length();
853         }
854         return count;
855     }
856
857     public static int count(String JavaDoc source, char c) {
858         return count(source, c, 0);
859     }
860     public static int count(String JavaDoc source, char c, int start) {
861         int count = 0;
862         int j = start;
863         while (true) {
864             int i = source.indexOf(c, j);
865             if (i == -1) {
866                 break;
867             }
868             count++;
869             j = i + 1;
870         }
871         return count;
872     }
873
874
875
876     /**
877      * Count substring occurrences in a source string, ignoring case.
878      *
879      * @param source source string
880      * @param sub substring to count
881      * @return number of substring occurrences
882      */

883     public static int countIgnoreCase(String JavaDoc source, String JavaDoc sub) {
884         int count = 0;
885         int j = 0;
886         while (true) {
887             int i = indexOfIgnoreCase(source, sub, j);
888             if (i == -1) {
889                 break;
890             }
891             count++;
892             j = i + sub.length();
893         }
894         return count;
895     }
896
897     // ---------------------------------------------------------------- string arrays
898

899     /**
900      * Finds the very first index of a substring from the specified array. It
901      * returns an int[2] where int[0] represents the substring index and int[1]
902      * represents position where substring was found. If noting found, int[0] will
903      * be equals to -1.
904      *
905      * @param s source string
906      * @param arr string array
907      *
908      * @return int[2]
909      */

910     public static int[] indexOf(String JavaDoc s, String JavaDoc arr[]) {
911         return indexOf(s, arr, 0);
912     }
913     /**
914      * Finds the very first index of a substring from the specified array. It
915      * returns an int[2] where int[0] represents the substring index and int[1]
916      * represents position where substring was found. If noting found, int[0] will
917      * be equals to -1.
918      *
919      * @param s source string
920      * @param arr string array
921      * @param start starting position
922      *
923      * @return int[2]
924      */

925     public static int[] indexOf(String JavaDoc s, String JavaDoc arr[], int start) {
926         int arrLen = arr.length;
927         int index = Integer.MAX_VALUE;
928         int last = -1;
929         for (int j = 0; j < arrLen; j++) {
930             int i = s.indexOf(arr[j], start);
931             if (i != -1) {
932                 if (i < index) {
933                     index = i;
934                     last = j;
935                 }
936             }
937         }
938         return new int[] {last, index};
939     }
940
941     /**
942      * Finds the very first index of a substring from the specified array. It
943      * returns an int[2] where int[0] represents the substring index and int[1]
944      * represents position where substring was found. If noting found, int[0] will
945      * be equals to -1.
946      *
947      * @param s source string
948      * @param arr string array
949      *
950      * @return int[2]
951      */

952     public static int[] indexOfIgnoreCase(String JavaDoc s, String JavaDoc arr[]) {
953         return indexOfIgnoreCase(s, arr, 0);
954     }
955     /**
956      * Finds the very first index of a substring from the specified array. It
957      * returns an int[2] where int[0] represents the substring index and int[1]
958      * represents position where substring was found. If noting found, int[0] will
959      * be equals to -1.
960      *
961      * @param s source string
962      * @param arr string array
963      * @param start starting position
964      *
965      * @return int[2]
966      */

967     public static int[] indexOfIgnoreCase(String JavaDoc s, String JavaDoc arr[], int start) {
968         int arrLen = arr.length;
969         int index = Integer.MAX_VALUE;
970         int last = -1;
971         for (int j = 0; j < arrLen; j++) {
972             int i = indexOfIgnoreCase(s, arr[j], start);
973             if (i != -1) {
974                 if (i < index) {
975                     index = i;
976                     last = j;
977                 }
978             }
979         }
980         return new int[] {last, index};
981     }
982
983     /**
984      * Finds the very last index of a substring from the specified array. It
985      * returns an int[2] where int[0] represents the substring index and int[1]
986      * represents position where substring was found. If noting found, int[0] will
987      * be equals to -1.
988      *
989      * @param s source string
990      * @param arr string array
991      *
992      * @return int[2]
993      */

994     public static int[] lastIndexOf(String JavaDoc s, String JavaDoc arr[]) {
995         return lastIndexOf(s, arr, s.length());
996     }
997     /**
998      * Finds the very last index of a substring from the specified array. It
999      * returns an int[2] where int[0] represents the substring index and int[1]
1000     * represents position where substring was found. If noting found, int[0] will
1001     * be equals to -1.
1002     *
1003     * @param s source string
1004     * @param arr string array
1005     * @param fromIndex starting position
1006     *
1007     * @return int[2]
1008     */

1009    public static int[] lastIndexOf(String JavaDoc s, String JavaDoc arr[], int fromIndex) {
1010        int arrLen = arr.length;
1011        int index = -1;
1012        int last = -1;
1013        for (int j = 0; j < arrLen; j++) {
1014            int i = s.lastIndexOf(arr[j], fromIndex);
1015            if (i != -1) {
1016                if (i > index) {
1017                    index = i;
1018                    last = j;
1019                }
1020            }
1021        }
1022        return new int[] {last, index};
1023    }
1024
1025    /**
1026     * Finds the very last index of a substring from the specified array. It
1027     * returns an int[2] where int[0] represents the substring index and int[1]
1028     * represents position where substring was found. If noting found, int[0] will
1029     * be equals to -1.
1030     *
1031     * @param s source string
1032     * @param arr string array
1033     *
1034     * @return int[2]
1035     */

1036    public static int[] lastIndexOfIgnoreCase(String JavaDoc s, String JavaDoc arr[]) {
1037        return lastIndexOfIgnoreCase(s, arr, s.length());
1038    }
1039    /**
1040     * Finds the very last index of a substring from the specified array. It
1041     * returns an int[2] where int[0] represents the substring index and int[1]
1042     * represents position where substring was found. If noting found, int[0] will
1043     * be equals to -1.
1044     *
1045     * @param s source string
1046     * @param arr string array
1047     * @param fromIndex starting position
1048     *
1049     * @return int[2]
1050     */

1051    public static int[] lastIndexOfIgnoreCase(String JavaDoc s, String JavaDoc arr[], int fromIndex) {
1052        int arrLen = arr.length;
1053        int index = -1;
1054        int last = -1;
1055        for (int j = 0; j < arrLen; j++) {
1056            int i = lastIndexOfIgnoreCase(s, arr[j], fromIndex);
1057            if (i != -1) {
1058                if (i > index) {
1059                    index = i;
1060                    last = j;
1061                }
1062            }
1063        }
1064        return new int[] {last, index};
1065    }
1066
1067    /**
1068     * Compares two string arrays.
1069     *
1070     * @param as first string array
1071     * @param as1 second string array
1072     *
1073     * @return <code>true</code> if all array elements matches
1074     */

1075    public static boolean equals(String JavaDoc as[], String JavaDoc as1[]) {
1076        if (as.length != as1.length) {
1077            return false;
1078        }
1079        for (int i = 0; i < as.length; i++) {
1080            if (as[i].equals(as1[i]) == false) {
1081                return false;
1082            }
1083        }
1084        return true;
1085    }
1086    /**
1087     * Compares two string arrays.
1088     *
1089     * @param as first string array
1090     * @param as1 second string array
1091     *
1092     * @return true if all array elements matches
1093     */

1094    public static boolean equalsIgnoreCase(String JavaDoc as[], String JavaDoc as1[]) {
1095        if (as.length != as1.length) {
1096            return false;
1097        }
1098        for (int i = 0; i < as.length; i++) {
1099            if (as[i].equalsIgnoreCase(as1[i]) == false) {
1100                return false;
1101            }
1102        }
1103        return true;
1104    }
1105
1106
1107    /**
1108     * Replaces many substring at once. Order of string array is important.
1109     *
1110     * @param s source string
1111     * @param sub substrings array
1112     * @param with replace with array
1113     *
1114     * @return string with all occurrences of substrings replaced
1115     */

1116    public static String JavaDoc replace(String JavaDoc s, String JavaDoc[] sub, String JavaDoc[] with) {
1117        if ((sub.length != with.length) || (sub.length == 0)) {
1118            return s;
1119        }
1120        int start = 0;
1121        StringBuffer JavaDoc buf = new StringBuffer JavaDoc(s.length());
1122        while (true) {
1123            int[] res = indexOf(s, sub, start);
1124            if (res[0] == -1) {
1125                break;
1126            }
1127            int end = res[1];
1128            buf.append(s.substring(start, end));
1129            buf.append(with[res[0]]);
1130            start = end + sub[res[0]].length();
1131        }
1132        buf.append(s.substring(start));
1133        return buf.toString();
1134    }
1135
1136    /**
1137     * Replaces many substring at once. Order of string array is important.
1138     *
1139     * @param s source string
1140     * @param sub substrings array
1141     * @param with replace with array
1142     *
1143     * @return string with all occurrences of substrings replaced
1144     */

1145    public static String JavaDoc replaceIgnoreCase(String JavaDoc s, String JavaDoc[] sub, String JavaDoc[] with) {
1146        if ((sub.length != with.length) || (sub.length == 0)) {
1147            return s;
1148        }
1149        int start = 0;
1150        StringBuffer JavaDoc buf = new StringBuffer JavaDoc(s.length());
1151        while (true) {
1152            int[] res = indexOfIgnoreCase(s, sub, start);
1153            if (res[0] == -1) {
1154                break;
1155            }
1156            int end = res[1];
1157            buf.append(s.substring(start, end));
1158            buf.append(with[res[0]]);
1159            start = end + sub[0].length();
1160        }
1161        buf.append(s.substring(start));
1162        return buf.toString();
1163    }
1164
1165
1166    // ---------------------------------------------------------------- the one
1167

1168    /**
1169     * Compares string with at least one from the provided array.
1170     * If at least one equal string is found, returns its index.
1171     * Otherwise, <code>-1</code> is returned.
1172     */

1173    public static int equalsOne(String JavaDoc src, String JavaDoc[] dest) {
1174        for (int i = 0; i < dest.length; i++) {
1175            if (src.equals(dest[i])) {
1176                return i;
1177            }
1178        }
1179        return -1;
1180    }
1181    /**
1182     * Compares string with at least one from the provided array, ignoring case.
1183     * If at least one equal string is found, it returns its index.
1184     * Otherwise, <code>-1</code> is returned.
1185     */

1186    public static int equalsOneIgnoreCase(String JavaDoc src, String JavaDoc[] dest) {
1187        for (int i = 0; i < dest.length; i++) {
1188            if (src.equalsIgnoreCase(dest[i])) {
1189                return i;
1190            }
1191        }
1192        return -1;
1193    }
1194
1195    /**
1196     * Checks if string starts with at least one string from the provided array.
1197     * If at least one string is matched, it returns its index.
1198     * Otherwise, <code>-1</code> is returned.
1199     */

1200    public static int startsWithOne(String JavaDoc src, String JavaDoc[] dest) {
1201        for (int i = 0; i < dest.length; i++) {
1202            if (src.startsWith(dest[i])) {
1203                return i;
1204            }
1205        }
1206        return -1;
1207    }
1208
1209    /**
1210     * Checks if string starts with at least one string from the provided array.
1211     * If at least one string is matched, it returns its index.
1212     * Otherwise, <code>-1</code> is returned.
1213     */

1214    public static int startsWithOneIgnoreCase(String JavaDoc src, String JavaDoc[] dest) {
1215        for (int i = 0; i < dest.length; i++) {
1216            if (startsWithIgnoreCase(src, dest[i])) {
1217                return i;
1218            }
1219        }
1220        return -1;
1221    }
1222
1223
1224    /**
1225     * Checks if string ends with at least one string from the provided array.
1226     * If at least one string is matched, it returns its index.
1227     * Otherwise, <code>-1</code> is returned.
1228     */

1229    public static int endsWithOne(String JavaDoc src, String JavaDoc[] dest) {
1230        for (int i = 0; i < dest.length; i++) {
1231            if (src.endsWith(dest[i])) {
1232                return i;
1233            }
1234        }
1235        return -1;
1236    }
1237
1238    /**
1239     * Checks if string ends with at least one string from the provided array.
1240     * If at least one string is matched, it returns its index.
1241     * Otherwise, <code>-1</code> is returned.
1242     */

1243    public static int endsWithOneIgnoreCase(String JavaDoc src, String JavaDoc[] dest) {
1244        for (int i = 0; i < dest.length; i++) {
1245            if (endsWithIgnoreCase(src, dest[i])) {
1246                return i;
1247            }
1248        }
1249        return -1;
1250    }
1251
1252
1253    // ---------------------------------------------------------------- char based
1254

1255
1256    public static int indexOfChars(String JavaDoc string, String JavaDoc chars) {
1257        return indexOfChars(string, chars, 0);
1258    }
1259
1260    /**
1261     * Returns the very first index of any char from provided string, starting from specified index offset.
1262     * Returns index of founded char, or <code>-1</code> if nothing found.
1263     */

1264    public static int indexOfChars(String JavaDoc string, String JavaDoc chars, int startindex) {
1265        int stringLen = string.length();
1266        int charsLen = chars.length();
1267        for (int i = startindex; i < stringLen; i++) {
1268            char c = string.charAt(i);
1269            for (int j = 0; j < charsLen; j++) {
1270                if (c == chars.charAt(j)) {
1271                    return i;
1272                }
1273            }
1274        }
1275        return -1;
1276    }
1277
1278    public static int indexOfChars(String JavaDoc string, char[] chars) {
1279        return indexOfChars(string, chars, 0);
1280    }
1281
1282    /**
1283     * Returns the very first index of any char from provided string, starting from specified index offset.
1284     * Returns index of founded char, or <code>-1</code> if nothing found.
1285     */

1286    public static int indexOfChars(String JavaDoc string, char[] chars, int startindex) {
1287        int stringLen = string.length();
1288        int charsLen = chars.length;
1289        for (int i = startindex; i < stringLen; i++) {
1290            char c = string.charAt(i);
1291            for (int j = 0; j < charsLen; j++) {
1292                if (c == chars[j]) {
1293                    return i;
1294                }
1295            }
1296        }
1297        return -1;
1298    }
1299
1300
1301    // ---------------------------------------------------------------- trim
1302

1303
1304    /**
1305     * Trims array of strings. Null elements of the array are ignored.
1306     */

1307    public static void trim(String JavaDoc[] strings) {
1308        for (int i = 0; i < strings.length; i++) {
1309            String JavaDoc string = strings[i];
1310            if (string != null) {
1311                strings[i] = string.trim();
1312            }
1313
1314        }
1315    }
1316
1317    /**
1318     * Trims array of strings where empty strings are nulled.
1319     * Null elements of the array are ignored.
1320     * @see #trimNonEmpty(String)
1321     */

1322    public static void trimNonEmpty(String JavaDoc[] strings) {
1323        for (int i = 0; i < strings.length; i++) {
1324            String JavaDoc string = strings[i];
1325            if (string != null) {
1326                strings[i] = trimNonEmpty(strings[i]);
1327            }
1328        }
1329    }
1330
1331
1332    /**
1333     * Trims string where empty strings are returned as a <code>null</code>.
1334     */

1335    public static String JavaDoc trimNonEmpty(String JavaDoc string) {
1336        if (string != null) {
1337            string = string.trim();
1338            if (string.length() == 0) {
1339                string = null;
1340            }
1341        }
1342        return string;
1343    }
1344
1345
1346    // ---------------------------------------------------------------- regions
1347

1348    /**
1349     * @see #indexOfRegion(String, String, String, int)
1350     */

1351    public static int[] indexOfRegion(String JavaDoc string, String JavaDoc leftBoundary, String JavaDoc rightBoundary) {
1352        return indexOfRegion(string, leftBoundary, rightBoundary, 0);
1353    }
1354
1355
1356    /**
1357     * Returns indexes of the first region without escaping character.
1358     * @see #indexOfRegion(String, String, String, char, int)
1359     */

1360    public static int[] indexOfRegion(String JavaDoc string, String JavaDoc leftBoundary, String JavaDoc rightBoundary, int offset) {
1361        int ndx = offset;
1362        int[] res = new int[4];
1363        ndx = string.indexOf(leftBoundary, ndx);
1364        if (ndx == -1) {
1365            return null;
1366        }
1367        res[0] = ndx;
1368        ndx += leftBoundary.length();
1369        res[1] = ndx;
1370
1371        ndx = string.indexOf(rightBoundary, ndx);
1372        if (ndx == -1) {
1373            return null;
1374        }
1375        res[2] = ndx;
1376        res[3] = ndx + rightBoundary.length();
1377        return res;
1378    }
1379
1380
1381    /**
1382     * @see #indexOfRegion(String, String, String, char, int)
1383     */

1384    public static int[] indexOfRegion(String JavaDoc string, String JavaDoc leftBoundary, String JavaDoc rightBoundary, char escape) {
1385        return indexOfRegion(string, leftBoundary, rightBoundary, escape, 0);
1386    }
1387
1388    /**
1389     * Returns indexes of the first string region. Region is defined by its left and right boundary.
1390     * Return value is an array of the following indexes:
1391     * <ul>
1392     * <li>start of left boundary index</li>
1393     * <li>region start index, i.e. end of left boundary</li>
1394     * <li>region end index, i.e. start of right boundary</li>
1395     * <li>end of right boundary index</li>
1396     * </ul>
1397     * <p>
1398     * Escape character may be used to prefix boundaries so they can be ignored.
1399     * If region is not founded, <code>null</code> is returned.
1400     */

1401    public static int[] indexOfRegion(String JavaDoc string, String JavaDoc leftBoundary, String JavaDoc rightBoundary, char escape, int offset) {
1402        int ndx = offset;
1403        int[] res = new int[4];
1404        while (true) {
1405            ndx = string.indexOf(leftBoundary, ndx);
1406            if (ndx == -1) {
1407                return null;
1408            }
1409            if (ndx > 0) {
1410                if (string.charAt(ndx - 1) == escape) {
1411                    ndx += leftBoundary.length();
1412                    continue;
1413                }
1414            }
1415            res[0] = ndx;
1416            ndx += leftBoundary.length();
1417            res[1] = ndx;
1418
1419            while (true) {
1420                ndx = string.indexOf(rightBoundary, ndx);
1421                if (ndx == -1) {
1422                    return null;
1423                }
1424                if (ndx > 0) {
1425                    if (string.charAt(ndx - 1) == escape) {
1426                        ndx += rightBoundary.length();
1427                        continue;
1428                    }
1429                }
1430                res[2] = ndx;
1431                res[3] = ndx + rightBoundary.length();
1432                return res;
1433            }
1434        }
1435    }
1436
1437
1438    // ---------------------------------------------------------------- charset
1439

1440    /**
1441     * Converts string charsets.
1442     */

1443    public static String JavaDoc convertCharset(String JavaDoc source, String JavaDoc srcCharsetName, String JavaDoc newCharsetName) throws UnsupportedEncodingException JavaDoc {
1444        return new String JavaDoc(source.getBytes(srcCharsetName), newCharsetName);
1445    }
1446
1447}
1448
Popular Tags