1 package com.sharkysoft.string;
2
3 import com.sharkysoft.util.UnreachableCodeException;
4
5 /***
6 * Miscellaneous string functions.
7 *
8 * <p><b>Details:</b> <code>StringToolbox</code> is a miscellaneous collection
9 * of functions for manipulating strings.</p>
10 *
11 * @author Sharky
12 */
13 public final class StringToolbox
14 {
15
16 private StringToolbox()
17 {
18 throw new UnreachableCodeException();
19 }
20
21 /***
22 // * Determines whether a string contains a character.
23 // *
24 // * <p><b>Details:</b> <code>contains</code> determines whether <var>c</var>
25 // * is contained within <var>string</var>, returning <code>true</code> if it
26 // * is, <code>false</code> otherwise.</p>
27 // *
28 // * @param string the string
29 // * @param c the character
30 // * @return true iff the string contains the substring
31 // *
32 // * @since 2001.03.09
33 // */
34
35
36
37
38
39 /***
40 // * Determines whether a string contains a substring.
41 // *
42 // * <p><b>Details:</b> <code>contains</code> determines whether
43 // * <var>substring</var> is contained within <var>string</var>, returning
44 // * <code>true</code> if it is, <code>false</code> if it is not.</p>
45 // *
46 // * @param string the string
47 // * @param substring the substring
48 // * @return true iff the string contains the substring
49 // *
50 // * @since 1999.04.16
51 // */
52
53
54
55
56
57 /***
58 // * Counts character occurrences.
59 // *
60 // * <p><b>Details:</b> <code>count</code> determines the number of occurrences
61 // * of a character in a string.</p>
62 // *
63 // * @param string the string to search
64 // * @param c the character
65 // * @return the number of occurrences
66 // */
67
68
69
70
71
72
73
74
75
76
77 /***
78 // * Counts substring occurences.
79 // *
80 // * <p><b>Details:</b> <code>count</code> determines the number of occurrences
81 // * of a substring string inside another string. Overlapping substrings are
82 // * counted. For example, the call</p>
83 // *
84 // * <blockquote><code>
85 // * count("banana", "ana")
86 // * </code></blockquote>
87 // *
88 // * <p>returns 2.</p>
89 // *
90 // * @param string the string to search
91 // * @param substring the substring
92 // * @return the number of occurrences
93 // */
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 /***
111 // * Finds first difference.
112 // *
113 // * <p><b>Details:</b> findDifference compares two strings, character for
114 // * character, starting with the first character, and scanning until a
115 // * character mismatch is encountered, or until the shorter string has run out
116 // * of characters. If a mismatch is encountered, the index of the mismatch is
117 // * returned. If no mismatches are found but the strings have unequal lengths,
118 // * the length of the shorter string is returned. If no mismatch is found and
119 // * the strings have equal length, then the strings are identical and -1 is
120 // * returned.</p>
121 // *
122 // * @param s1 the first string
123 // * @param s2 the second string
124 // * @return the index of mismatch
125 // *
126 // * @since 2000.02.16
127 // */
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144 /***
145 // * Determines common suffix.
146 // *
147 // * <p><b>Details:</b> getCommonSuffix returns the longest string that is a
148 // * suffix to both given strings.</p>
149 // *
150 // * @param s1 the first string
151 // * @param s2 the second string
152 // * @return the suffix
153 // *
154 // * @since 2001.03.09
155 // */
156
157
158
159
160
161
162
163
164
165
166
167
168 /***
169 // * Returns left portion of string.
170 // *
171 // * <p><b>Details:</b> <code>left</code> returns a prefix of the given string
172 // * of the requested length. If the requested length is greater than the
173 // * length of the original string, the original string is returned.</p>
174 // *
175 // * @param s the string whose prefix is desired
176 // * @param len the length of the prefix
177 // * @return the prefix
178 // */
179
180
181
182
183
184
185
186 /***
187 // * Removes excess spaces.
188 // *
189 // * <p><b>Details:</b> <code>minimizeSpaces</code> removes excess white spaces
190 // * from the ends and middle of the given string. Space characters are
191 // * identified in the same manner as they are identified by
192 // * <code>java.util.StringTokenizer</code> when an instance is created without
193 // * delimeters. A space is considered excess if any of the following
194 // * conditions regarding that space are true:</p>
195 // *
196 // * <ul>
197 // * <li>It is at the beginning of the string.</li>
198 // * <li>It is at the end of the string.</li>
199 // * <li>It is preceded by another white space.</li>
200 // * </ul>
201 // *
202 // * <p>After all excess spaces are removed, all remaining spaces are converted
203 // * into normal spaces, and the resulting string is returned.</p>
204 // *
205 // * @param s the string to process
206 // * @return the processed string
207 // */
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 /***
223 * Creates string by repeating character.
224 *
225 * <p><b>Details:</b> <code>repeat</code> creates a new string by repeating a
226 * character. For example, the call</p>
227 *
228 * <blockquote><code>
229 * repeat('#', 3)
230 * </code></blockquote>
231 *
232 * <p>produces the string "<tt>###</tt>". A zero-<wbr>length string is
233 * returned if the repeat count is less than 1.</p>
234 *
235 * @param icChar the character to repeat
236 * @param inCount the repeat count
237 * @return the new string containing repeated characters
238 */
239 public static String repeat(char icChar, int inCount)
240 {
241 StringBuffer buff = new StringBuffer(inCount);
242 for (int i = 0; i < inCount; ++i)
243 buff.append(icChar);
244 return buff.toString();
245 }
246
247 /***
248 // * Creates string by repeating string.
249 // *
250 // * <p><b>Details:</b> <code>repeat</code> creates a new <code>String</code> by
251 // * repeating and concatenating the contents of another <code>String</code>
252 // * (<var>s</var>). For example, the call</p>
253 // *
254 // * <blockquote><code>
255 // * repeat ("Hello", 3)
256 // * </code></blockquote>
257 // *
258 // * <p>produces the string "<tt>HelloHelloHello</tt>". <code>repeat</code>
259 // * returns a zero-length string if the repeat count (<var>n</var>) is less
260 // * than 1.</p>
261 // *
262 // * @param s the string to repeat
263 // * @param n the repeat count
264 // * @return the new string containing repeated substrings
265 // */
266
267
268
269
270
271
272
273
274 /***
275 // * Search and replace.
276 // *
277 // * <p><b>Details:</b> <code>replace</code> scans <var>source</var> for
278 // * substrings matching <var>before</var>, from left to right, and replaces all
279 // * occurrences found with <var>after</var>. If a matching substring is found,
280 // * the replacement is made and then the scan picks up after the last character
281 // * of the substring. The result is returned in a new string. If no
282 // * replacements were made, the original <code>String</code> instance is
283 // * returned.</p>
284 // *
285 // * @param source the source string
286 // * @param before the substring to search for
287 // * @param after what to replace <var>before</var> with
288 // * @return the new string
289 // *
290 // * @since 2000.01.30
291 // */
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324 /***
325 // * Returns suffix of string.
326 // *
327 // * <p><b>Details:</b> <code>right</code> returns a suffix of the given string
328 // * of the requested length. If the requested length is greater than the
329 // * length of the original string, the original string is returned.</p>
330 // *
331 // * @param s the string whose suffix is desired
332 // * @param len length of desired suffix
333 // * @return the suffix
334 // */
335
336
337
338
339
340
341
342
343 /***
344 // * Divides string into tokens.
345 // *
346 // * <p><b>Details:</b> <code>splitString</code> breaks a string (<var>s</var>)
347 // * into an array of substrings with the delimeters removed. The delimeter
348 // * characters are listed in a separate string (<var>d</var>).</p>
349 // *
350 // * <p><code>java.util.StringTokenizer</code> offers similar functionality.
351 // * This implementation differs by the fact that it returns all of the tokens
352 // * at once, using a <code>String</code> array, and does not require the
353 // * explicit creation of a tokenizer object or enumeration handling.</p>
354 // *
355 // * @param s the string to split
356 // * @param d the delimeters
357 // * @return the substrings of s
358 // */
359
360
361
362
363
364
365
366
367
368
369 /***
370 // * Converts string to "title" case.
371 // *
372 // * <p><b>Details:</b> This method converts the first character of every run
373 // * of letters in the given string (<var>s</var>) to upper case, making the
374 // * string appear in "title" format. For the purposes of conversion,
375 // * apostrophes occuring immediately after letters are also treated as letters.
376 // * This method may not be appropriate for some strings, particularly those
377 // * containing Roman numerals and other words where more than one character
378 // * should be capitalized.</p>
379 // *
380 // * <p>Examples:</p>
381 // *
382 // * <table>
383 // * <tr>
384 // * <td>MacDonald's</td>
385 // * <td>Macdonald's</td>
386 // * </tr>
387 // * <tr>
388 // * <td>yo-yos</td>
389 // * <td>Yo-Yos</td>
390 // * </tr>
391 // * <tr>
392 // * <td>part</td>
393 // * <td>Part</td>
394 // * </tr>
395 // * <tr>
396 // * <td>III</td>
397 // * <td>Iii</td>
398 // * </tr>
399 // * </table>
400 // *
401 // * @param s the string to convert
402 // * @return the converted string
403 // *
404 // * @since 2000.01.15
405 // */
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430 /***
431 // * Trims characters from both ends of string.
432 // *
433 // * <p><b>Details:</b> <code>trim</code> removes the given character
434 // * (<var>c</var>) from both ends of the given string (<var>s</var>). For
435 // * example, the call</p>
436 // *
437 // * <blockquote><code>
438 // * trimTrailing ("sizes", 's')
439 // * </code></blockquote>
440 // *
441 // * <p>returns the string "<tt>ize</tt>".</p>
442 // *
443 // * @param s the string to edit
444 // * @param n the character to trim
445 // * @return the trimmed string
446 // */
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 /***
462 // * Trims trailing characters.
463 // *
464 // * <p><b>Details:</b> <code>trimTrailing</code> trims the specified character
465 // * (<var>c</var>) from the end of the given string (<var>s</var>) if the
466 // * string ends with one or more repetitions of that character. For example,
467 // * the call</p>
468 // *
469 // * <blockquote><code>
470 // * removeTrailing("Tennessee", 'e')
471 // * </code></blockquote>
472 // *
473 // * <p>returns the string "<tt>Tenness</tt>".</p>
474 // *
475 // * @param s the string to edit
476 // * @param c the trailing character to remove
477 // * @return a new string with the trailing characters removed
478 // */
479
480
481
482
483
484
485
486
487
488 /***
489 // * Trims leading characters.
490 // *
491 // * <p><b>Details:</b> <code>trimLeading</code> trims occurances of the
492 // * specified character (<var>ic</var>) from the beginning of the given string
493 // * (<var>is</var>) if the string begins with one or more repetitions of that
494 // * character. For example, the call</p>
495 // *
496 // * <blockquote><code>
497 // * removeLeading ("eery", 'e')
498 // * </code></blockquote>
499 // *
500 // * <p>returns the string "<tt>ry</tt>".</p>
501 // *
502 // * @param is the string to edit
503 // * @param ic the leading character to remove
504 // * @return a new string with the leading characters removed
505 // *
506 // * @since 2001.09.08
507 // */
508
509
510
511
512
513
514
515
516
517
518
519
520 /***
521 // * Determines if string looks like an email address.
522 // *
523 // * <p><b>Details:</b> <code>looksLikeAnEmailAddress</code> analyzes the given
524 // * string (<var>s</var>) and determines whether it looks like an email
525 // * address. If it does, <code>looksLikeAnEmailAddress</code> returns
526 // * <code>true</code>, <code>false</code> otherwise.</p>
527 // *
528 // * <p>See {@link com.sharkysoft.io.StreamParser#tryEmailAddress()
529 // * <code>com.sharkysoft.io.StreamParser.tryEmailAddress</code>} for more
530 // * information on the forms of email addresses accepted by this function.</p>
531 // *
532 // * @param s the string to test
533 // * @return true iff s looks like an email address
534 // *
535 // * @since 2000.12.21
536 // */
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555 }
556