Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: libadblockplus-android/src/org/apache/commons/lang/StringUtils.java

Issue 29348972: Issue 4239 - Change indentation to reflect our coding style (Closed)
Patch Set: Created Aug. 2, 2016, 10:43 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Simplified by Andrey Novikov for AdBlock Plus 2 * Simplified by Andrey Novikov for AdBlock Plus
3 */ 3 */
4 4
5 /* 5 /*
6 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * Licensed to the Apache Software Foundation (ASF) under one or more
7 * contributor license agreements. See the NOTICE file distributed with 7 * contributor license agreements. See the NOTICE file distributed with
8 * this work for additional information regarding copyright ownership. 8 * this work for additional information regarding copyright ownership.
9 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * The ASF licenses this file to You under the Apache License, Version 2.0
10 * (the "License"); you may not use this file except in compliance with 10 * (the "License"); you may not use this file except in compliance with
11 * the License. You may obtain a copy of the License at 11 * the License. You may obtain a copy of the License at
12 * 12 *
13 * http://www.apache.org/licenses/LICENSE-2.0 13 * http://www.apache.org/licenses/LICENSE-2.0
14 * 14 *
15 * Unless required by applicable law or agreed to in writing, software 15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS, 16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and 18 * See the License for the specific language governing permissions and
19 * limitations under the License. 19 * limitations under the License.
20 */ 20 */
21 package org.apache.commons.lang; 21 package org.apache.commons.lang;
22 22
23 23
24 /** 24 /**
25 * <p>Operations on {@link java.lang.String} that are 25 * <p>Operations on {@link java.lang.String} that are
26 * <code>null</code> safe.</p> 26 * <code>null</code> safe.</p>
27 * 27 * <p/>
28 * <ul> 28 * <ul>
29 * <li><b>IsEmpty/IsBlank</b> 29 * <li><b>IsEmpty/IsBlank</b>
30 * - checks if a String contains text</li> 30 * - checks if a String contains text</li>
31 * <li><b>Trim/Strip</b> 31 * <li><b>Trim/Strip</b>
32 * - removes leading and trailing whitespace</li> 32 * - removes leading and trailing whitespace</li>
33 * <li><b>Equals</b> 33 * <li><b>Equals</b>
34 * - compares two strings null-safe</li> 34 * - compares two strings null-safe</li>
35 * <li><b>startsWith</b> 35 * <li><b>startsWith</b>
36 * - check if a String starts with a prefix null-safe</li> 36 * - check if a String starts with a prefix null-safe</li>
37 * <li><b>endsWith</b> 37 * <li><b>endsWith</b>
38 * - check if a String ends with a suffix null-safe</li> 38 * - check if a String ends with a suffix null-safe</li>
39 * <li><b>IndexOf/LastIndexOf/Contains</b> 39 * <li><b>IndexOf/LastIndexOf/Contains</b>
40 * - null-safe index-of checks 40 * - null-safe index-of checks
41 * <li><b>IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut</b> 41 * <li><b>IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut</b>
42 * - index-of any of a set of Strings</li> 42 * - index-of any of a set of Strings</li>
43 * <li><b>ContainsOnly/ContainsNone/ContainsAny</b> 43 * <li><b>ContainsOnly/ContainsNone/ContainsAny</b>
44 * - does String contains only/none/any of these characters</li> 44 * - does String contains only/none/any of these characters</li>
45 * <li><b>Substring/Left/Right/Mid</b> 45 * <li><b>Substring/Left/Right/Mid</b>
46 * - null-safe substring extractions</li> 46 * - null-safe substring extractions</li>
47 * <li><b>SubstringBefore/SubstringAfter/SubstringBetween</b> 47 * <li><b>SubstringBefore/SubstringAfter/SubstringBetween</b>
48 * - substring extraction relative to other strings</li> 48 * - substring extraction relative to other strings</li>
49 * <li><b>Split/Join</b> 49 * <li><b>Split/Join</b>
50 * - splits a String into an array of substrings and vice versa</li> 50 * - splits a String into an array of substrings and vice versa</li>
51 * <li><b>Remove/Delete</b> 51 * <li><b>Remove/Delete</b>
52 * - removes part of a String</li> 52 * - removes part of a String</li>
53 * <li><b>Replace/Overlay</b> 53 * <li><b>Replace/Overlay</b>
54 * - Searches a String and replaces one String with another</li> 54 * - Searches a String and replaces one String with another</li>
55 * <li><b>Chomp/Chop</b> 55 * <li><b>Chomp/Chop</b>
56 * - removes the last part of a String</li> 56 * - removes the last part of a String</li>
57 * <li><b>LeftPad/RightPad/Center/Repeat</b> 57 * <li><b>LeftPad/RightPad/Center/Repeat</b>
58 * - pads a String</li> 58 * - pads a String</li>
59 * <li><b>UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize</b> 59 * <li><b>UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize</b>
60 * - changes the case of a String</li> 60 * - changes the case of a String</li>
61 * <li><b>CountMatches</b> 61 * <li><b>CountMatches</b>
62 * - counts the number of occurrences of one String in another</li> 62 * - counts the number of occurrences of one String in another</li>
63 * <li><b>IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable</b> 63 * <li><b>IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable</b>
64 * - checks the characters in a String</li> 64 * - checks the characters in a String</li>
65 * <li><b>DefaultString</b> 65 * <li><b>DefaultString</b>
66 * - protects against a null input String</li> 66 * - protects against a null input String</li>
67 * <li><b>Reverse/ReverseDelimited</b> 67 * <li><b>Reverse/ReverseDelimited</b>
68 * - reverses a String</li> 68 * - reverses a String</li>
69 * <li><b>Abbreviate</b> 69 * <li><b>Abbreviate</b>
70 * - abbreviates a string using ellipsis</li> 70 * - abbreviates a string using ellipsis</li>
71 * <li><b>Difference</b> 71 * <li><b>Difference</b>
72 * - compares Strings and reports on their differences</li> 72 * - compares Strings and reports on their differences</li>
73 * <li><b>LevensteinDistance</b> 73 * <li><b>LevensteinDistance</b>
74 * - the number of changes needed to change one String into another</li> 74 * - the number of changes needed to change one String into another</li>
75 * </ul> 75 * </ul>
76 * 76 * <p/>
77 * <p>The <code>StringUtils</code> class defines certain words related to 77 * <p>The <code>StringUtils</code> class defines certain words related to
78 * String handling.</p> 78 * String handling.</p>
79 * 79 * <p/>
80 * <ul> 80 * <ul>
81 * <li>null - <code>null</code></li> 81 * <li>null - <code>null</code></li>
82 * <li>empty - a zero-length string (<code>""</code>)</li> 82 * <li>empty - a zero-length string (<code>""</code>)</li>
83 * <li>space - the space character (<code>' '</code>, char 32)</li> 83 * <li>space - the space character (<code>' '</code>, char 32)</li>
84 * <li>whitespace - the characters defined by {@link Character#isWhitespace(cha r)}</li> 84 * <li>whitespace - the characters defined by {@link Character#isWhitespace(char )}</li>
85 * <li>trim - the characters &lt;= 32 as in {@link String#trim()}</li> 85 * <li>trim - the characters &lt;= 32 as in {@link String#trim()}</li>
86 * </ul> 86 * </ul>
87 * 87 * <p/>
88 * <p><code>StringUtils</code> handles <code>null</code> input Strings quietly. 88 * <p><code>StringUtils</code> handles <code>null</code> input Strings quietly.
89 * That is to say that a <code>null</code> input will return <code>null</code>. 89 * That is to say that a <code>null</code> input will return <code>null</code>.
90 * Where a <code>boolean</code> or <code>int</code> is being returned 90 * Where a <code>boolean</code> or <code>int</code> is being returned
91 * details vary by method.</p> 91 * details vary by method.</p>
92 * 92 * <p/>
93 * <p>A side effect of the <code>null</code> handling is that a 93 * <p>A side effect of the <code>null</code> handling is that a
94 * <code>NullPointerException</code> should be considered a bug in 94 * <code>NullPointerException</code> should be considered a bug in
95 * <code>StringUtils</code> (except for deprecated methods).</p> 95 * <code>StringUtils</code> (except for deprecated methods).</p>
96 * 96 * <p/>
97 * <p>Methods in this class give sample code to explain their operation. 97 * <p>Methods in this class give sample code to explain their operation.
98 * The symbol <code>*</code> is used to indicate any input including <code>null< /code>.</p> 98 * The symbol <code>*</code> is used to indicate any input including <code>null< /code>.</p>
99 * 99 *
100 * @see java.lang.String
101 * @author <a href="http://jakarta.apache.org/turbine/">Apache Jakarta Turbine</ a> 100 * @author <a href="http://jakarta.apache.org/turbine/">Apache Jakarta Turbine</ a>
102 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> 101 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
103 * @author Daniel L. Rall 102 * @author Daniel L. Rall
104 * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a> 103 * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
105 * @author <a href="mailto:ed@apache.org">Ed Korthof</a> 104 * @author <a href="mailto:ed@apache.org">Ed Korthof</a>
106 * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a> 105 * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
107 * @author Stephen Colebourne 106 * @author Stephen Colebourne
108 * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a> 107 * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
109 * @author Holger Krauth 108 * @author Holger Krauth
110 * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a> 109 * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
111 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 110 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
112 * @author Arun Mammen Thomas 111 * @author Arun Mammen Thomas
113 * @author Gary Gregory 112 * @author Gary Gregory
114 * @author Phil Steitz 113 * @author Phil Steitz
115 * @author Al Chou 114 * @author Al Chou
116 * @author Michael Davey 115 * @author Michael Davey
117 * @author Reuben Sivan 116 * @author Reuben Sivan
118 * @author Chris Hyzer 117 * @author Chris Hyzer
119 * @author Scott Johnson 118 * @author Scott Johnson
119 * @version $Id: StringUtils.java 635447 2008-03-10 06:27:09Z bayard $
120 * @see java.lang.String
120 * @since 1.0 121 * @since 1.0
121 * @version $Id: StringUtils.java 635447 2008-03-10 06:27:09Z bayard $
122 */ 122 */
123 public class StringUtils { 123 public class StringUtils
124 // Performance testing notes (JDK 1.4, Jul03, scolebourne) 124 {
125 // Whitespace: 125 // Performance testing notes (JDK 1.4, Jul03, scolebourne)
126 // Character.isWhitespace() is faster than WHITESPACE.indexOf() 126 // Whitespace:
127 // where WHITESPACE is a string of all whitespace characters 127 // Character.isWhitespace() is faster than WHITESPACE.indexOf()
128 // 128 // where WHITESPACE is a string of all whitespace characters
129 // Character access: 129 //
130 // String.charAt(n) versus toCharArray(), then array[n] 130 // Character access:
131 // String.charAt(n) is about 15% worse for a 10K string 131 // String.charAt(n) versus toCharArray(), then array[n]
132 // They are about equal for a length 50 string 132 // String.charAt(n) is about 15% worse for a 10K string
133 // String.charAt(n) is about 4 times better for a length 3 string 133 // They are about equal for a length 50 string
134 // String.charAt(n) is best bet overall 134 // String.charAt(n) is about 4 times better for a length 3 string
135 // 135 // String.charAt(n) is best bet overall
136 // Append: 136 //
137 // String.concat about twice as fast as StringBuffer.append 137 // Append:
138 // (not sure who tested this) 138 // String.concat about twice as fast as StringBuffer.append
139 139 // (not sure who tested this)
140 /** 140
141 * The empty String <code>""</code>. 141 /**
142 * @since 2.0 142 * The empty String <code>""</code>.
143 */ 143 *
144 public static final String EMPTY = ""; 144 * @since 2.0
145 145 */
146 /** 146 public static final String EMPTY = "";
147 * Represents a failed index search. 147
148 * @since 2.1 148 /**
149 */ 149 * Represents a failed index search.
150 public static final int INDEX_NOT_FOUND = -1; 150 *
151 151 * @since 2.1
152 /** 152 */
153 * <p>The maximum size to which the padding constant(s) can expand.</p> 153 public static final int INDEX_NOT_FOUND = -1;
154 */ 154
155 private static final int PAD_LIMIT = 8192; 155 /**
156 156 * <p>The maximum size to which the padding constant(s) can expand.</p>
157 /** 157 */
158 * <p><code>StringUtils</code> instances should NOT be constructed in 158 private static final int PAD_LIMIT = 8192;
159 * standard programming. Instead, the class should be used as 159
160 * <code>StringUtils.trim(" foo ");</code>.</p> 160 /**
161 * 161 * <p><code>StringUtils</code> instances should NOT be constructed in
162 * <p>This constructor is public to permit tools that require a JavaBean 162 * standard programming. Instead, the class should be used as
163 * instance to operate.</p> 163 * <code>StringUtils.trim(" foo ");</code>.</p>
164 */ 164 * <p/>
165 public StringUtils() { 165 * <p>This constructor is public to permit tools that require a JavaBean
166 super(); 166 * instance to operate.</p>
167 } 167 */
168 168 public StringUtils()
169 // Empty checks 169 {
170 //----------------------------------------------------------------------- 170 super();
171 /** 171 }
172 * <p>Checks if a String is empty ("") or null.</p> 172
173 * 173 // Empty checks
174 * <pre> 174 //-----------------------------------------------------------------------
175 * StringUtils.isEmpty(null) = true 175
176 * StringUtils.isEmpty("") = true 176 /**
177 * StringUtils.isEmpty(" ") = false 177 * <p>Checks if a String is empty ("") or null.</p>
178 * StringUtils.isEmpty("bob") = false 178 * <p/>
179 * StringUtils.isEmpty(" bob ") = false 179 * <pre>
180 * </pre> 180 * StringUtils.isEmpty(null) = true
181 * 181 * StringUtils.isEmpty("") = true
182 * <p>NOTE: This method changed in Lang version 2.0. 182 * StringUtils.isEmpty(" ") = false
183 * It no longer trims the String. 183 * StringUtils.isEmpty("bob") = false
184 * That functionality is available in isBlank().</p> 184 * StringUtils.isEmpty(" bob ") = false
185 * 185 * </pre>
186 * @param str the String to check, may be null 186 * <p/>
187 * @return <code>true</code> if the String is empty or null 187 * <p>NOTE: This method changed in Lang version 2.0.
188 */ 188 * It no longer trims the String.
189 public static boolean isEmpty(String str) { 189 * That functionality is available in isBlank().</p>
190 return str == null || str.length() == 0; 190 *
191 } 191 * @param str the String to check, may be null
192 192 * @return <code>true</code> if the String is empty or null
193 /** 193 */
194 * <p>Checks if a String is not empty ("") and not null.</p> 194 public static boolean isEmpty(String str)
195 * 195 {
196 * <pre> 196 return str == null || str.length() == 0;
197 * StringUtils.isNotEmpty(null) = false 197 }
198 * StringUtils.isNotEmpty("") = false 198
199 * StringUtils.isNotEmpty(" ") = true 199 /**
200 * StringUtils.isNotEmpty("bob") = true 200 * <p>Checks if a String is not empty ("") and not null.</p>
201 * StringUtils.isNotEmpty(" bob ") = true 201 * <p/>
202 * </pre> 202 * <pre>
203 * 203 * StringUtils.isNotEmpty(null) = false
204 * @param str the String to check, may be null 204 * StringUtils.isNotEmpty("") = false
205 * @return <code>true</code> if the String is not empty and not null 205 * StringUtils.isNotEmpty(" ") = true
206 */ 206 * StringUtils.isNotEmpty("bob") = true
207 public static boolean isNotEmpty(String str) { 207 * StringUtils.isNotEmpty(" bob ") = true
208 return !StringUtils.isEmpty(str); 208 * </pre>
209 } 209 *
210 210 * @param str the String to check, may be null
211 /** 211 * @return <code>true</code> if the String is not empty and not null
212 * <p>Checks if a String is whitespace, empty ("") or null.</p> 212 */
213 * 213 public static boolean isNotEmpty(String str)
214 * <pre> 214 {
215 * StringUtils.isBlank(null) = true 215 return !StringUtils.isEmpty(str);
216 * StringUtils.isBlank("") = true 216 }
217 * StringUtils.isBlank(" ") = true 217
218 * StringUtils.isBlank("bob") = false 218 /**
219 * StringUtils.isBlank(" bob ") = false 219 * <p>Checks if a String is whitespace, empty ("") or null.</p>
220 * </pre> 220 * <p/>
221 * 221 * <pre>
222 * @param str the String to check, may be null 222 * StringUtils.isBlank(null) = true
223 * @return <code>true</code> if the String is null, empty or whitespace 223 * StringUtils.isBlank("") = true
224 * @since 2.0 224 * StringUtils.isBlank(" ") = true
225 */ 225 * StringUtils.isBlank("bob") = false
226 public static boolean isBlank(String str) { 226 * StringUtils.isBlank(" bob ") = false
227 int strLen; 227 * </pre>
228 if (str == null || (strLen = str.length()) == 0) { 228 *
229 return true; 229 * @param str the String to check, may be null
230 * @return <code>true</code> if the String is null, empty or whitespace
231 * @since 2.0
232 */
233 public static boolean isBlank(String str)
234 {
235 int strLen;
236 if (str == null || (strLen = str.length()) == 0)
237 {
238 return true;
239 }
240 for (int i = 0; i < strLen; i++)
241 {
242 if ((Character.isWhitespace(str.charAt(i)) == false))
243 {
244 return false;
245 }
246 }
247 return true;
248 }
249
250 /**
251 * <p>Checks if a String is not empty (""), not null and not whitespace only.< /p>
252 * <p/>
253 * <pre>
254 * StringUtils.isNotBlank(null) = false
255 * StringUtils.isNotBlank("") = false
256 * StringUtils.isNotBlank(" ") = false
257 * StringUtils.isNotBlank("bob") = true
258 * StringUtils.isNotBlank(" bob ") = true
259 * </pre>
260 *
261 * @param str the String to check, may be null
262 * @return <code>true</code> if the String is
263 * not empty and not null and not whitespace
264 * @since 2.0
265 */
266 public static boolean isNotBlank(String str)
267 {
268 return !StringUtils.isBlank(str);
269 }
270
271 // Trim
272 //-----------------------------------------------------------------------
273
274 /**
275 * <p>Removes control characters (char &lt;= 32) from both
276 * ends of this String, handling <code>null</code> by returning
277 * an empty String ("").</p>
278 * <p/>
279 * <pre>
280 * StringUtils.clean(null) = ""
281 * StringUtils.clean("") = ""
282 * StringUtils.clean("abc") = "abc"
283 * StringUtils.clean(" abc ") = "abc"
284 * StringUtils.clean(" ") = ""
285 * </pre>
286 *
287 * @param str the String to clean, may be null
288 * @return the trimmed text, never <code>null</code>
289 * @see java.lang.String#trim()
290 * @deprecated Use the clearer named {@link #trimToEmpty(String)}.
291 * Method will be removed in Commons Lang 3.0.
292 */
293 public static String clean(String str)
294 {
295 return str == null ? EMPTY : str.trim();
296 }
297
298 /**
299 * <p>Removes control characters (char &lt;= 32) from both
300 * ends of this String, handling <code>null</code> by returning
301 * <code>null</code>.</p>
302 * <p/>
303 * <p>The String is trimmed using {@link String#trim()}.
304 * Trim removes start and end characters &lt;= 32.
305 * To strip whitespace use {@link #strip(String)}.</p>
306 * <p/>
307 * <p>To trim your choice of characters, use the
308 * {@link #strip(String, String)} methods.</p>
309 * <p/>
310 * <pre>
311 * StringUtils.trim(null) = null
312 * StringUtils.trim("") = ""
313 * StringUtils.trim(" ") = ""
314 * StringUtils.trim("abc") = "abc"
315 * StringUtils.trim(" abc ") = "abc"
316 * </pre>
317 *
318 * @param str the String to be trimmed, may be null
319 * @return the trimmed string, <code>null</code> if null String input
320 */
321 public static String trim(String str)
322 {
323 return str == null ? null : str.trim();
324 }
325
326 /**
327 * <p>Removes control characters (char &lt;= 32) from both
328 * ends of this String returning <code>null</code> if the String is
329 * empty ("") after the trim or if it is <code>null</code>.
330 * <p/>
331 * <p>The String is trimmed using {@link String#trim()}.
332 * Trim removes start and end characters &lt;= 32.
333 * To strip whitespace use {@link #stripToNull(String)}.</p>
334 * <p/>
335 * <pre>
336 * StringUtils.trimToNull(null) = null
337 * StringUtils.trimToNull("") = null
338 * StringUtils.trimToNull(" ") = null
339 * StringUtils.trimToNull("abc") = "abc"
340 * StringUtils.trimToNull(" abc ") = "abc"
341 * </pre>
342 *
343 * @param str the String to be trimmed, may be null
344 * @return the trimmed String,
345 * <code>null</code> if only chars &lt;= 32, empty or null String input
346 * @since 2.0
347 */
348 public static String trimToNull(String str)
349 {
350 String ts = trim(str);
351 return isEmpty(ts) ? null : ts;
352 }
353
354 /**
355 * <p>Removes control characters (char &lt;= 32) from both
356 * ends of this String returning an empty String ("") if the String
357 * is empty ("") after the trim or if it is <code>null</code>.
358 * <p/>
359 * <p>The String is trimmed using {@link String#trim()}.
360 * Trim removes start and end characters &lt;= 32.
361 * To strip whitespace use {@link #stripToEmpty(String)}.</p>
362 * <p/>
363 * <pre>
364 * StringUtils.trimToEmpty(null) = ""
365 * StringUtils.trimToEmpty("") = ""
366 * StringUtils.trimToEmpty(" ") = ""
367 * StringUtils.trimToEmpty("abc") = "abc"
368 * StringUtils.trimToEmpty(" abc ") = "abc"
369 * </pre>
370 *
371 * @param str the String to be trimmed, may be null
372 * @return the trimmed String, or an empty String if <code>null</code> input
373 * @since 2.0
374 */
375 public static String trimToEmpty(String str)
376 {
377 return str == null ? EMPTY : str.trim();
378 }
379
380 // Stripping
381 //-----------------------------------------------------------------------
382
383 /**
384 * <p>Strips whitespace from the start and end of a String.</p>
385 * <p/>
386 * <p>This is similar to {@link #trim(String)} but removes whitespace.
387 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
388 * <p/>
389 * <p>A <code>null</code> input String returns <code>null</code>.</p>
390 * <p/>
391 * <pre>
392 * StringUtils.strip(null) = null
393 * StringUtils.strip("") = ""
394 * StringUtils.strip(" ") = ""
395 * StringUtils.strip("abc") = "abc"
396 * StringUtils.strip(" abc") = "abc"
397 * StringUtils.strip("abc ") = "abc"
398 * StringUtils.strip(" abc ") = "abc"
399 * StringUtils.strip(" ab c ") = "ab c"
400 * </pre>
401 *
402 * @param str the String to remove whitespace from, may be null
403 * @return the stripped String, <code>null</code> if null String input
404 */
405 public static String strip(String str)
406 {
407 return strip(str, null);
408 }
409
410 /**
411 * <p>Strips whitespace from the start and end of a String returning
412 * <code>null</code> if the String is empty ("") after the strip.</p>
413 * <p/>
414 * <p>This is similar to {@link #trimToNull(String)} but removes whitespace.
415 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
416 * <p/>
417 * <pre>
418 * StringUtils.stripToNull(null) = null
419 * StringUtils.stripToNull("") = null
420 * StringUtils.stripToNull(" ") = null
421 * StringUtils.stripToNull("abc") = "abc"
422 * StringUtils.stripToNull(" abc") = "abc"
423 * StringUtils.stripToNull("abc ") = "abc"
424 * StringUtils.stripToNull(" abc ") = "abc"
425 * StringUtils.stripToNull(" ab c ") = "ab c"
426 * </pre>
427 *
428 * @param str the String to be stripped, may be null
429 * @return the stripped String,
430 * <code>null</code> if whitespace, empty or null String input
431 * @since 2.0
432 */
433 public static String stripToNull(String str)
434 {
435 if (str == null)
436 {
437 return null;
438 }
439 str = strip(str, null);
440 return str.length() == 0 ? null : str;
441 }
442
443 /**
444 * <p>Strips whitespace from the start and end of a String returning
445 * an empty String if <code>null</code> input.</p>
446 * <p/>
447 * <p>This is similar to {@link #trimToEmpty(String)} but removes whitespace.
448 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
449 * <p/>
450 * <pre>
451 * StringUtils.stripToEmpty(null) = ""
452 * StringUtils.stripToEmpty("") = ""
453 * StringUtils.stripToEmpty(" ") = ""
454 * StringUtils.stripToEmpty("abc") = "abc"
455 * StringUtils.stripToEmpty(" abc") = "abc"
456 * StringUtils.stripToEmpty("abc ") = "abc"
457 * StringUtils.stripToEmpty(" abc ") = "abc"
458 * StringUtils.stripToEmpty(" ab c ") = "ab c"
459 * </pre>
460 *
461 * @param str the String to be stripped, may be null
462 * @return the trimmed String, or an empty String if <code>null</code> input
463 * @since 2.0
464 */
465 public static String stripToEmpty(String str)
466 {
467 return str == null ? EMPTY : strip(str, null);
468 }
469
470 /**
471 * <p>Strips any of a set of characters from the start and end of a String.
472 * This is similar to {@link String#trim()} but allows the characters
473 * to be stripped to be controlled.</p>
474 * <p/>
475 * <p>A <code>null</code> input String returns <code>null</code>.
476 * An empty string ("") input returns the empty string.</p>
477 * <p/>
478 * <p>If the stripChars String is <code>null</code>, whitespace is
479 * stripped as defined by {@link Character#isWhitespace(char)}.
480 * Alternatively use {@link #strip(String)}.</p>
481 * <p/>
482 * <pre>
483 * StringUtils.strip(null, *) = null
484 * StringUtils.strip("", *) = ""
485 * StringUtils.strip("abc", null) = "abc"
486 * StringUtils.strip(" abc", null) = "abc"
487 * StringUtils.strip("abc ", null) = "abc"
488 * StringUtils.strip(" abc ", null) = "abc"
489 * StringUtils.strip(" abcyx", "xyz") = " abc"
490 * </pre>
491 *
492 * @param str the String to remove characters from, may be null
493 * @param stripChars the characters to remove, null treated as whitespace
494 * @return the stripped String, <code>null</code> if null String input
495 */
496 public static String strip(String str, String stripChars)
497 {
498 if (isEmpty(str))
499 {
500 return str;
501 }
502 str = stripStart(str, stripChars);
503 return stripEnd(str, stripChars);
504 }
505
506 /**
507 * <p>Strips any of a set of characters from the start of a String.</p>
508 * <p/>
509 * <p>A <code>null</code> input String returns <code>null</code>.
510 * An empty string ("") input returns the empty string.</p>
511 * <p/>
512 * <p>If the stripChars String is <code>null</code>, whitespace is
513 * stripped as defined by {@link Character#isWhitespace(char)}.</p>
514 * <p/>
515 * <pre>
516 * StringUtils.stripStart(null, *) = null
517 * StringUtils.stripStart("", *) = ""
518 * StringUtils.stripStart("abc", "") = "abc"
519 * StringUtils.stripStart("abc", null) = "abc"
520 * StringUtils.stripStart(" abc", null) = "abc"
521 * StringUtils.stripStart("abc ", null) = "abc "
522 * StringUtils.stripStart(" abc ", null) = "abc "
523 * StringUtils.stripStart("yxabc ", "xyz") = "abc "
524 * </pre>
525 *
526 * @param str the String to remove characters from, may be null
527 * @param stripChars the characters to remove, null treated as whitespace
528 * @return the stripped String, <code>null</code> if null String input
529 */
530 public static String stripStart(String str, String stripChars)
531 {
532 int strLen;
533 if (str == null || (strLen = str.length()) == 0)
534 {
535 return str;
536 }
537 int start = 0;
538 if (stripChars == null)
539 {
540 while ((start != strLen) && Character.isWhitespace(str.charAt(start)))
541 {
542 start++;
543 }
544 } else if (stripChars.length() == 0)
545 {
546 return str;
547 } else
548 {
549 while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != -1))
550 {
551 start++;
552 }
553 }
554 return str.substring(start);
555 }
556
557 /**
558 * <p>Strips any of a set of characters from the end of a String.</p>
559 * <p/>
560 * <p>A <code>null</code> input String returns <code>null</code>.
561 * An empty string ("") input returns the empty string.</p>
562 * <p/>
563 * <p>If the stripChars String is <code>null</code>, whitespace is
564 * stripped as defined by {@link Character#isWhitespace(char)}.</p>
565 * <p/>
566 * <pre>
567 * StringUtils.stripEnd(null, *) = null
568 * StringUtils.stripEnd("", *) = ""
569 * StringUtils.stripEnd("abc", "") = "abc"
570 * StringUtils.stripEnd("abc", null) = "abc"
571 * StringUtils.stripEnd(" abc", null) = " abc"
572 * StringUtils.stripEnd("abc ", null) = "abc"
573 * StringUtils.stripEnd(" abc ", null) = " abc"
574 * StringUtils.stripEnd(" abcyx", "xyz") = " abc"
575 * </pre>
576 *
577 * @param str the String to remove characters from, may be null
578 * @param stripChars the characters to remove, null treated as whitespace
579 * @return the stripped String, <code>null</code> if null String input
580 */
581 public static String stripEnd(String str, String stripChars)
582 {
583 int end;
584 if (str == null || (end = str.length()) == 0)
585 {
586 return str;
587 }
588
589 if (stripChars == null)
590 {
591 while ((end != 0) && Character.isWhitespace(str.charAt(end - 1)))
592 {
593 end--;
594 }
595 } else if (stripChars.length() == 0)
596 {
597 return str;
598 } else
599 {
600 while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != -1))
601 {
602 end--;
603 }
604 }
605 return str.substring(0, end);
606 }
607
608 // StripAll
609 //-----------------------------------------------------------------------
610
611 /**
612 * <p>Strips whitespace from the start and end of every String in an array.
613 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
614 * <p/>
615 * <p>A new array is returned each time, except for length zero.
616 * A <code>null</code> array will return <code>null</code>.
617 * An empty array will return itself.
618 * A <code>null</code> array entry will be ignored.</p>
619 * <p/>
620 * <pre>
621 * StringUtils.stripAll(null) = null
622 * StringUtils.stripAll([]) = []
623 * StringUtils.stripAll(["abc", " abc"]) = ["abc", "abc"]
624 * StringUtils.stripAll(["abc ", null]) = ["abc", null]
625 * </pre>
626 *
627 * @param strs the array to remove whitespace from, may be null
628 * @return the stripped Strings, <code>null</code> if null array input
629 */
630 public static String[] stripAll(String[] strs)
631 {
632 return stripAll(strs, null);
633 }
634
635 /**
636 * <p>Strips any of a set of characters from the start and end of every
637 * String in an array.</p>
638 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
639 * <p/>
640 * <p>A new array is returned each time, except for length zero.
641 * A <code>null</code> array will return <code>null</code>.
642 * An empty array will return itself.
643 * A <code>null</code> array entry will be ignored.
644 * A <code>null</code> stripChars will strip whitespace as defined by
645 * {@link Character#isWhitespace(char)}.</p>
646 * <p/>
647 * <pre>
648 * StringUtils.stripAll(null, *) = null
649 * StringUtils.stripAll([], *) = []
650 * StringUtils.stripAll(["abc", " abc"], null) = ["abc", "abc"]
651 * StringUtils.stripAll(["abc ", null], null) = ["abc", null]
652 * StringUtils.stripAll(["abc ", null], "yz") = ["abc ", null]
653 * StringUtils.stripAll(["yabcz", null], "yz") = ["abc", null]
654 * </pre>
655 *
656 * @param strs the array to remove characters from, may be null
657 * @param stripChars the characters to remove, null treated as whitespace
658 * @return the stripped Strings, <code>null</code> if null array input
659 */
660 public static String[] stripAll(String[] strs, String stripChars)
661 {
662 int strsLen;
663 if (strs == null || (strsLen = strs.length) == 0)
664 {
665 return strs;
666 }
667 String[] newArr = new String[strsLen];
668 for (int i = 0; i < strsLen; i++)
669 {
670 newArr[i] = strip(strs[i], stripChars);
671 }
672 return newArr;
673 }
674
675 // Equals
676 //-----------------------------------------------------------------------
677
678 /**
679 * <p>Compares two Strings, returning <code>true</code> if they are equal.</p>
680 * <p/>
681 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
682 * references are considered to be equal. The comparison is case sensitive.</p >
683 * <p/>
684 * <pre>
685 * StringUtils.equals(null, null) = true
686 * StringUtils.equals(null, "abc") = false
687 * StringUtils.equals("abc", null) = false
688 * StringUtils.equals("abc", "abc") = true
689 * StringUtils.equals("abc", "ABC") = false
690 * </pre>
691 *
692 * @param str1 the first String, may be null
693 * @param str2 the second String, may be null
694 * @return <code>true</code> if the Strings are equal, case sensitive, or
695 * both <code>null</code>
696 * @see java.lang.String#equals(Object)
697 */
698 public static boolean equals(String str1, String str2)
699 {
700 return str1 == null ? str2 == null : str1.equals(str2);
701 }
702
703 /**
704 * <p>Compares two Strings, returning <code>true</code> if they are equal igno ring
705 * the case.</p>
706 * <p/>
707 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
708 * references are considered equal. Comparison is case insensitive.</p>
709 * <p/>
710 * <pre>
711 * StringUtils.equalsIgnoreCase(null, null) = true
712 * StringUtils.equalsIgnoreCase(null, "abc") = false
713 * StringUtils.equalsIgnoreCase("abc", null) = false
714 * StringUtils.equalsIgnoreCase("abc", "abc") = true
715 * StringUtils.equalsIgnoreCase("abc", "ABC") = true
716 * </pre>
717 *
718 * @param str1 the first String, may be null
719 * @param str2 the second String, may be null
720 * @return <code>true</code> if the Strings are equal, case insensitive, or
721 * both <code>null</code>
722 * @see java.lang.String#equalsIgnoreCase(String)
723 */
724 public static boolean equalsIgnoreCase(String str1, String str2)
725 {
726 return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2);
727 }
728
729 // IndexOf
730 //-----------------------------------------------------------------------
731
732 /**
733 * <p>Finds the first index within a String, handling <code>null</code>.
734 * This method uses {@link String#indexOf(int)}.</p>
735 * <p/>
736 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.</p >
737 * <p/>
738 * <pre>
739 * StringUtils.indexOf(null, *) = -1
740 * StringUtils.indexOf("", *) = -1
741 * StringUtils.indexOf("aabaabaa", 'a') = 0
742 * StringUtils.indexOf("aabaabaa", 'b') = 2
743 * </pre>
744 *
745 * @param str the String to check, may be null
746 * @param searchChar the character to find
747 * @return the first index of the search character,
748 * -1 if no match or <code>null</code> string input
749 * @since 2.0
750 */
751 public static int indexOf(String str, char searchChar)
752 {
753 if (isEmpty(str))
754 {
755 return -1;
756 }
757 return str.indexOf(searchChar);
758 }
759
760 /**
761 * <p>Finds the first index within a String from a start position,
762 * handling <code>null</code>.
763 * This method uses {@link String#indexOf(int, int)}.</p>
764 * <p/>
765 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.
766 * A negative start position is treated as zero.
767 * A start position greater than the string length returns <code>-1</code>.</p >
768 * <p/>
769 * <pre>
770 * StringUtils.indexOf(null, *, *) = -1
771 * StringUtils.indexOf("", *, *) = -1
772 * StringUtils.indexOf("aabaabaa", 'b', 0) = 2
773 * StringUtils.indexOf("aabaabaa", 'b', 3) = 5
774 * StringUtils.indexOf("aabaabaa", 'b', 9) = -1
775 * StringUtils.indexOf("aabaabaa", 'b', -1) = 2
776 * </pre>
777 *
778 * @param str the String to check, may be null
779 * @param searchChar the character to find
780 * @param startPos the start position, negative treated as zero
781 * @return the first index of the search character,
782 * -1 if no match or <code>null</code> string input
783 * @since 2.0
784 */
785 public static int indexOf(String str, char searchChar, int startPos)
786 {
787 if (isEmpty(str))
788 {
789 return -1;
790 }
791 return str.indexOf(searchChar, startPos);
792 }
793
794 /**
795 * <p>Finds the first index within a String, handling <code>null</code>.
796 * This method uses {@link String#indexOf(String)}.</p>
797 * <p/>
798 * <p>A <code>null</code> String will return <code>-1</code>.</p>
799 * <p/>
800 * <pre>
801 * StringUtils.indexOf(null, *) = -1
802 * StringUtils.indexOf(*, null) = -1
803 * StringUtils.indexOf("", "") = 0
804 * StringUtils.indexOf("aabaabaa", "a") = 0
805 * StringUtils.indexOf("aabaabaa", "b") = 2
806 * StringUtils.indexOf("aabaabaa", "ab") = 1
807 * StringUtils.indexOf("aabaabaa", "") = 0
808 * </pre>
809 *
810 * @param str the String to check, may be null
811 * @param searchStr the String to find, may be null
812 * @return the first index of the search String,
813 * -1 if no match or <code>null</code> string input
814 * @since 2.0
815 */
816 public static int indexOf(String str, String searchStr)
817 {
818 if (str == null || searchStr == null)
819 {
820 return -1;
821 }
822 return str.indexOf(searchStr);
823 }
824
825 /**
826 * <p>Finds the n-th index within a String, handling <code>null</code>.
827 * This method uses {@link String#indexOf(String)}.</p>
828 * <p/>
829 * <p>A <code>null</code> String will return <code>-1</code>.</p>
830 * <p/>
831 * <pre>
832 * StringUtils.ordinalIndexOf(null, *, *) = -1
833 * StringUtils.ordinalIndexOf(*, null, *) = -1
834 * StringUtils.ordinalIndexOf("", "", *) = 0
835 * StringUtils.ordinalIndexOf("aabaabaa", "a", 1) = 0
836 * StringUtils.ordinalIndexOf("aabaabaa", "a", 2) = 1
837 * StringUtils.ordinalIndexOf("aabaabaa", "b", 1) = 2
838 * StringUtils.ordinalIndexOf("aabaabaa", "b", 2) = 5
839 * StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1
840 * StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4
841 * StringUtils.ordinalIndexOf("aabaabaa", "", 1) = 0
842 * StringUtils.ordinalIndexOf("aabaabaa", "", 2) = 0
843 * </pre>
844 *
845 * @param str the String to check, may be null
846 * @param searchStr the String to find, may be null
847 * @param ordinal the n-th <code>searchStr</code> to find
848 * @return the n-th index of the search String,
849 * <code>-1</code> (<code>INDEX_NOT_FOUND</code>) if no match or <code>null</c ode> string input
850 * @since 2.1
851 */
852 public static int ordinalIndexOf(String str, String searchStr, int ordinal)
853 {
854 if (str == null || searchStr == null || ordinal <= 0)
855 {
856 return INDEX_NOT_FOUND;
857 }
858 if (searchStr.length() == 0)
859 {
860 return 0;
861 }
862 int found = 0;
863 int index = INDEX_NOT_FOUND;
864 do
865 {
866 index = str.indexOf(searchStr, index + 1);
867 if (index < 0)
868 {
869 return index;
870 }
871 found++;
872 } while (found < ordinal);
873 return index;
874 }
875
876 /**
877 * <p>Finds the first index within a String, handling <code>null</code>.
878 * This method uses {@link String#indexOf(String, int)}.</p>
879 * <p/>
880 * <p>A <code>null</code> String will return <code>-1</code>.
881 * A negative start position is treated as zero.
882 * An empty ("") search String always matches.
883 * A start position greater than the string length only matches
884 * an empty search String.</p>
885 * <p/>
886 * <pre>
887 * StringUtils.indexOf(null, *, *) = -1
888 * StringUtils.indexOf(*, null, *) = -1
889 * StringUtils.indexOf("", "", 0) = 0
890 * StringUtils.indexOf("aabaabaa", "a", 0) = 0
891 * StringUtils.indexOf("aabaabaa", "b", 0) = 2
892 * StringUtils.indexOf("aabaabaa", "ab", 0) = 1
893 * StringUtils.indexOf("aabaabaa", "b", 3) = 5
894 * StringUtils.indexOf("aabaabaa", "b", 9) = -1
895 * StringUtils.indexOf("aabaabaa", "b", -1) = 2
896 * StringUtils.indexOf("aabaabaa", "", 2) = 2
897 * StringUtils.indexOf("abc", "", 9) = 3
898 * </pre>
899 *
900 * @param str the String to check, may be null
901 * @param searchStr the String to find, may be null
902 * @param startPos the start position, negative treated as zero
903 * @return the first index of the search String,
904 * -1 if no match or <code>null</code> string input
905 * @since 2.0
906 */
907 public static int indexOf(String str, String searchStr, int startPos)
908 {
909 if (str == null || searchStr == null)
910 {
911 return -1;
912 }
913 // JDK1.2/JDK1.3 have a bug, when startPos > str.length for "", hence
914 if (searchStr.length() == 0 && startPos >= str.length())
915 {
916 return str.length();
917 }
918 return str.indexOf(searchStr, startPos);
919 }
920
921 // LastIndexOf
922 //-----------------------------------------------------------------------
923
924 /**
925 * <p>Finds the last index within a String, handling <code>null</code>.
926 * This method uses {@link String#lastIndexOf(int)}.</p>
927 * <p/>
928 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.</p >
929 * <p/>
930 * <pre>
931 * StringUtils.lastIndexOf(null, *) = -1
932 * StringUtils.lastIndexOf("", *) = -1
933 * StringUtils.lastIndexOf("aabaabaa", 'a') = 7
934 * StringUtils.lastIndexOf("aabaabaa", 'b') = 5
935 * </pre>
936 *
937 * @param str the String to check, may be null
938 * @param searchChar the character to find
939 * @return the last index of the search character,
940 * -1 if no match or <code>null</code> string input
941 * @since 2.0
942 */
943 public static int lastIndexOf(String str, char searchChar)
944 {
945 if (isEmpty(str))
946 {
947 return -1;
948 }
949 return str.lastIndexOf(searchChar);
950 }
951
952 /**
953 * <p>Finds the last index within a String from a start position,
954 * handling <code>null</code>.
955 * This method uses {@link String#lastIndexOf(int, int)}.</p>
956 * <p/>
957 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.
958 * A negative start position returns <code>-1</code>.
959 * A start position greater than the string length searches the whole string.< /p>
960 * <p/>
961 * <pre>
962 * StringUtils.lastIndexOf(null, *, *) = -1
963 * StringUtils.lastIndexOf("", *, *) = -1
964 * StringUtils.lastIndexOf("aabaabaa", 'b', 8) = 5
965 * StringUtils.lastIndexOf("aabaabaa", 'b', 4) = 2
966 * StringUtils.lastIndexOf("aabaabaa", 'b', 0) = -1
967 * StringUtils.lastIndexOf("aabaabaa", 'b', 9) = 5
968 * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1
969 * StringUtils.lastIndexOf("aabaabaa", 'a', 0) = 0
970 * </pre>
971 *
972 * @param str the String to check, may be null
973 * @param searchChar the character to find
974 * @param startPos the start position
975 * @return the last index of the search character,
976 * -1 if no match or <code>null</code> string input
977 * @since 2.0
978 */
979 public static int lastIndexOf(String str, char searchChar, int startPos)
980 {
981 if (isEmpty(str))
982 {
983 return -1;
984 }
985 return str.lastIndexOf(searchChar, startPos);
986 }
987
988 /**
989 * <p>Finds the last index within a String, handling <code>null</code>.
990 * This method uses {@link String#lastIndexOf(String)}.</p>
991 * <p/>
992 * <p>A <code>null</code> String will return <code>-1</code>.</p>
993 * <p/>
994 * <pre>
995 * StringUtils.lastIndexOf(null, *) = -1
996 * StringUtils.lastIndexOf(*, null) = -1
997 * StringUtils.lastIndexOf("", "") = 0
998 * StringUtils.lastIndexOf("aabaabaa", "a") = 0
999 * StringUtils.lastIndexOf("aabaabaa", "b") = 2
1000 * StringUtils.lastIndexOf("aabaabaa", "ab") = 1
1001 * StringUtils.lastIndexOf("aabaabaa", "") = 8
1002 * </pre>
1003 *
1004 * @param str the String to check, may be null
1005 * @param searchStr the String to find, may be null
1006 * @return the last index of the search String,
1007 * -1 if no match or <code>null</code> string input
1008 * @since 2.0
1009 */
1010 public static int lastIndexOf(String str, String searchStr)
1011 {
1012 if (str == null || searchStr == null)
1013 {
1014 return -1;
1015 }
1016 return str.lastIndexOf(searchStr);
1017 }
1018
1019 /**
1020 * <p>Finds the first index within a String, handling <code>null</code>.
1021 * This method uses {@link String#lastIndexOf(String, int)}.</p>
1022 * <p/>
1023 * <p>A <code>null</code> String will return <code>-1</code>.
1024 * A negative start position returns <code>-1</code>.
1025 * An empty ("") search String always matches unless the start position is neg ative.
1026 * A start position greater than the string length searches the whole string.< /p>
1027 * <p/>
1028 * <pre>
1029 * StringUtils.lastIndexOf(null, *, *) = -1
1030 * StringUtils.lastIndexOf(*, null, *) = -1
1031 * StringUtils.lastIndexOf("aabaabaa", "a", 8) = 7
1032 * StringUtils.lastIndexOf("aabaabaa", "b", 8) = 5
1033 * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4
1034 * StringUtils.lastIndexOf("aabaabaa", "b", 9) = 5
1035 * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1
1036 * StringUtils.lastIndexOf("aabaabaa", "a", 0) = 0
1037 * StringUtils.lastIndexOf("aabaabaa", "b", 0) = -1
1038 * </pre>
1039 *
1040 * @param str the String to check, may be null
1041 * @param searchStr the String to find, may be null
1042 * @param startPos the start position, negative treated as zero
1043 * @return the first index of the search String,
1044 * -1 if no match or <code>null</code> string input
1045 * @since 2.0
1046 */
1047 public static int lastIndexOf(String str, String searchStr, int startPos)
1048 {
1049 if (str == null || searchStr == null)
1050 {
1051 return -1;
1052 }
1053 return str.lastIndexOf(searchStr, startPos);
1054 }
1055
1056 // Contains
1057 //-----------------------------------------------------------------------
1058
1059 /**
1060 * <p>Checks if String contains a search character, handling <code>null</code> .
1061 * This method uses {@link String#indexOf(int)}.</p>
1062 * <p/>
1063 * <p>A <code>null</code> or empty ("") String will return <code>false</code>. </p>
1064 * <p/>
1065 * <pre>
1066 * StringUtils.contains(null, *) = false
1067 * StringUtils.contains("", *) = false
1068 * StringUtils.contains("abc", 'a') = true
1069 * StringUtils.contains("abc", 'z') = false
1070 * </pre>
1071 *
1072 * @param str the String to check, may be null
1073 * @param searchChar the character to find
1074 * @return true if the String contains the search character,
1075 * false if not or <code>null</code> string input
1076 * @since 2.0
1077 */
1078 public static boolean contains(String str, char searchChar)
1079 {
1080 if (isEmpty(str))
1081 {
1082 return false;
1083 }
1084 return str.indexOf(searchChar) >= 0;
1085 }
1086
1087 /**
1088 * <p>Checks if String contains a search String, handling <code>null</code>.
1089 * This method uses {@link String#indexOf(String)}.</p>
1090 * <p/>
1091 * <p>A <code>null</code> String will return <code>false</code>.</p>
1092 * <p/>
1093 * <pre>
1094 * StringUtils.contains(null, *) = false
1095 * StringUtils.contains(*, null) = false
1096 * StringUtils.contains("", "") = true
1097 * StringUtils.contains("abc", "") = true
1098 * StringUtils.contains("abc", "a") = true
1099 * StringUtils.contains("abc", "z") = false
1100 * </pre>
1101 *
1102 * @param str the String to check, may be null
1103 * @param searchStr the String to find, may be null
1104 * @return true if the String contains the search String,
1105 * false if not or <code>null</code> string input
1106 * @since 2.0
1107 */
1108 public static boolean contains(String str, String searchStr)
1109 {
1110 if (str == null || searchStr == null)
1111 {
1112 return false;
1113 }
1114 return str.indexOf(searchStr) >= 0;
1115 }
1116
1117 /**
1118 * <p>Checks if String contains a search String irrespective of case,
1119 * handling <code>null</code>. This method uses
1120 * {@link #contains(String, String)}.</p>
1121 * <p/>
1122 * <p>A <code>null</code> String will return <code>false</code>.</p>
1123 * <p/>
1124 * <pre>
1125 * StringUtils.contains(null, *) = false
1126 * StringUtils.contains(*, null) = false
1127 * StringUtils.contains("", "") = true
1128 * StringUtils.contains("abc", "") = true
1129 * StringUtils.contains("abc", "a") = true
1130 * StringUtils.contains("abc", "z") = false
1131 * StringUtils.contains("abc", "A") = true
1132 * StringUtils.contains("abc", "Z") = false
1133 * </pre>
1134 *
1135 * @param str the String to check, may be null
1136 * @param searchStr the String to find, may be null
1137 * @return true if the String contains the search String irrespective of
1138 * case or false if not or <code>null</code> string input
1139 */
1140 public static boolean containsIgnoreCase(String str, String searchStr)
1141 {
1142 if (str == null || searchStr == null)
1143 {
1144 return false;
1145 }
1146 return contains(str.toUpperCase(), searchStr.toUpperCase());
1147 }
1148
1149 // ContainsAny
1150 //-----------------------------------------------------------------------
1151
1152 /**
1153 * <p>Checks if the String contains any character in the given
1154 * set of characters.</p>
1155 * <p/>
1156 * <p>A <code>null</code> String will return <code>false</code>.
1157 * A <code>null</code> or zero length search array will return <code>false</co de>.</p>
1158 * <p/>
1159 * <pre>
1160 * StringUtils.containsAny(null, *) = false
1161 * StringUtils.containsAny("", *) = false
1162 * StringUtils.containsAny(*, null) = false
1163 * StringUtils.containsAny(*, []) = false
1164 * StringUtils.containsAny("zzabyycdxx",['z','a']) = true
1165 * StringUtils.containsAny("zzabyycdxx",['b','y']) = true
1166 * StringUtils.containsAny("aba", ['z']) = false
1167 * </pre>
1168 *
1169 * @param str the String to check, may be null
1170 * @param searchChars the chars to search for, may be null
1171 * @return the <code>true</code> if any of the chars are found,
1172 * <code>false</code> if no match or null input
1173 * @since 2.4
1174 */
1175 public static boolean containsAny(String str, char[] searchChars)
1176 {
1177 if (str == null || str.length() == 0 || searchChars == null || searchChars.l ength == 0)
1178 {
1179 return false;
1180 }
1181 for (int i = 0; i < str.length(); i++)
1182 {
1183 char ch = str.charAt(i);
1184 for (int j = 0; j < searchChars.length; j++)
1185 {
1186 if (searchChars[j] == ch)
1187 {
1188 return true;
230 } 1189 }
231 for (int i = 0; i < strLen; i++) { 1190 }
232 if ((Character.isWhitespace(str.charAt(i)) == false)) { 1191 }
233 return false; 1192 return false;
234 } 1193 }
1194
1195 /**
1196 * <p>
1197 * Checks if the String contains any character in the given set of characters.
1198 * </p>
1199 * <p/>
1200 * <p>
1201 * A <code>null</code> String will return <code>false</code>. A <code>null</co de> search string will return
1202 * <code>false</code>.
1203 * </p>
1204 * <p/>
1205 * <pre>
1206 * StringUtils.containsAny(null, *) = false
1207 * StringUtils.containsAny("", *) = false
1208 * StringUtils.containsAny(*, null) = false
1209 * StringUtils.containsAny(*, "") = false
1210 * StringUtils.containsAny("zzabyycdxx", "za") = true
1211 * StringUtils.containsAny("zzabyycdxx", "by") = true
1212 * StringUtils.containsAny("aba","z") = false
1213 * </pre>
1214 *
1215 * @param str the String to check, may be null
1216 * @param searchChars the chars to search for, may be null
1217 * @return the <code>true</code> if any of the chars are found, <code>false</c ode> if no match or null input
1218 * @since 2.4
1219 */
1220 public static boolean containsAny(String str, String searchChars)
1221 {
1222 if (searchChars == null)
1223 {
1224 return false;
1225 }
1226 return containsAny(str, searchChars.toCharArray());
1227 }
1228
1229 /**
1230 * <p>Search a String to find the first index of any
1231 * character not in the given set of characters.</p>
1232 * <p/>
1233 * <p>A <code>null</code> String will return <code>-1</code>.
1234 * A <code>null</code> search string will return <code>-1</code>.</p>
1235 * <p/>
1236 * <pre>
1237 * StringUtils.indexOfAnyBut(null, *) = -1
1238 * StringUtils.indexOfAnyBut("", *) = -1
1239 * StringUtils.indexOfAnyBut(*, null) = -1
1240 * StringUtils.indexOfAnyBut(*, "") = -1
1241 * StringUtils.indexOfAnyBut("zzabyycdxx", "za") = 3
1242 * StringUtils.indexOfAnyBut("zzabyycdxx", "") = 0
1243 * StringUtils.indexOfAnyBut("aba","ab") = -1
1244 * </pre>
1245 *
1246 * @param str the String to check, may be null
1247 * @param searchChars the chars to search for, may be null
1248 * @return the index of any of the chars, -1 if no match or null input
1249 * @since 2.0
1250 */
1251 public static int indexOfAnyBut(String str, String searchChars)
1252 {
1253 if (isEmpty(str) || isEmpty(searchChars))
1254 {
1255 return -1;
1256 }
1257 for (int i = 0; i < str.length(); i++)
1258 {
1259 if (searchChars.indexOf(str.charAt(i)) < 0)
1260 {
1261 return i;
1262 }
1263 }
1264 return -1;
1265 }
1266
1267 // ContainsNone
1268 //-----------------------------------------------------------------------
1269
1270 /**
1271 * <p>Checks that the String does not contain certain characters.</p>
1272 * <p/>
1273 * <p>A <code>null</code> String will return <code>true</code>.
1274 * A <code>null</code> invalid character array will return <code>true</code>.
1275 * An empty String ("") always returns true.</p>
1276 * <p/>
1277 * <pre>
1278 * StringUtils.containsNone(null, *) = true
1279 * StringUtils.containsNone(*, null) = true
1280 * StringUtils.containsNone("", *) = true
1281 * StringUtils.containsNone("ab", '') = true
1282 * StringUtils.containsNone("abab", 'xyz') = true
1283 * StringUtils.containsNone("ab1", 'xyz') = true
1284 * StringUtils.containsNone("abz", 'xyz') = false
1285 * </pre>
1286 *
1287 * @param str the String to check, may be null
1288 * @param invalidChars an array of invalid chars, may be null
1289 * @return true if it contains none of the invalid chars, or is null
1290 * @since 2.0
1291 */
1292 public static boolean containsNone(String str, char[] invalidChars)
1293 {
1294 if (str == null || invalidChars == null)
1295 {
1296 return true;
1297 }
1298 int strSize = str.length();
1299 int validSize = invalidChars.length;
1300 for (int i = 0; i < strSize; i++)
1301 {
1302 char ch = str.charAt(i);
1303 for (int j = 0; j < validSize; j++)
1304 {
1305 if (invalidChars[j] == ch)
1306 {
1307 return false;
235 } 1308 }
236 return true; 1309 }
237 } 1310 }
238 1311 return true;
239 /** 1312 }
240 * <p>Checks if a String is not empty (""), not null and not whitespace only .</p> 1313
241 * 1314 /**
242 * <pre> 1315 * <p>Checks that the String does not contain certain characters.</p>
243 * StringUtils.isNotBlank(null) = false 1316 * <p/>
244 * StringUtils.isNotBlank("") = false 1317 * <p>A <code>null</code> String will return <code>true</code>.
245 * StringUtils.isNotBlank(" ") = false 1318 * A <code>null</code> invalid character array will return <code>true</code>.
246 * StringUtils.isNotBlank("bob") = true 1319 * An empty String ("") always returns true.</p>
247 * StringUtils.isNotBlank(" bob ") = true 1320 * <p/>
248 * </pre> 1321 * <pre>
249 * 1322 * StringUtils.containsNone(null, *) = true
250 * @param str the String to check, may be null 1323 * StringUtils.containsNone(*, null) = true
251 * @return <code>true</code> if the String is 1324 * StringUtils.containsNone("", *) = true
252 * not empty and not null and not whitespace 1325 * StringUtils.containsNone("ab", "") = true
253 * @since 2.0 1326 * StringUtils.containsNone("abab", "xyz") = true
254 */ 1327 * StringUtils.containsNone("ab1", "xyz") = true
255 public static boolean isNotBlank(String str) { 1328 * StringUtils.containsNone("abz", "xyz") = false
256 return !StringUtils.isBlank(str); 1329 * </pre>
257 } 1330 *
258 1331 * @param str the String to check, may be null
259 // Trim 1332 * @param invalidChars a String of invalid chars, may be null
260 //----------------------------------------------------------------------- 1333 * @return true if it contains none of the invalid chars, or is null
261 /** 1334 * @since 2.0
262 * <p>Removes control characters (char &lt;= 32) from both 1335 */
263 * ends of this String, handling <code>null</code> by returning 1336 public static boolean containsNone(String str, String invalidChars)
264 * an empty String ("").</p> 1337 {
265 * 1338 if (str == null || invalidChars == null)
266 * <pre> 1339 {
267 * StringUtils.clean(null) = "" 1340 return true;
268 * StringUtils.clean("") = "" 1341 }
269 * StringUtils.clean("abc") = "abc" 1342 return containsNone(str, invalidChars.toCharArray());
270 * StringUtils.clean(" abc ") = "abc" 1343 }
271 * StringUtils.clean(" ") = "" 1344
272 * </pre> 1345 // IndexOfAny strings
273 * 1346 //-----------------------------------------------------------------------
274 * @see java.lang.String#trim() 1347
275 * @param str the String to clean, may be null 1348 /**
276 * @return the trimmed text, never <code>null</code> 1349 * <p>Find the first index of any of a set of potential substrings.</p>
277 * @deprecated Use the clearer named {@link #trimToEmpty(String)}. 1350 * <p/>
278 * Method will be removed in Commons Lang 3.0. 1351 * <p>A <code>null</code> String will return <code>-1</code>.
279 */ 1352 * A <code>null</code> or zero length search array will return <code>-1</code> .
280 public static String clean(String str) { 1353 * A <code>null</code> search array entry will be ignored, but a search
281 return str == null ? EMPTY : str.trim(); 1354 * array containing "" will return <code>0</code> if <code>str</code> is not
282 } 1355 * null. This method uses {@link String#indexOf(String)}.</p>
283 1356 * <p/>
284 /** 1357 * <pre>
285 * <p>Removes control characters (char &lt;= 32) from both 1358 * StringUtils.indexOfAny(null, *) = -1
286 * ends of this String, handling <code>null</code> by returning 1359 * StringUtils.indexOfAny(*, null) = -1
287 * <code>null</code>.</p> 1360 * StringUtils.indexOfAny(*, []) = -1
288 * 1361 * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"]) = 2
289 * <p>The String is trimmed using {@link String#trim()}. 1362 * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"]) = 2
290 * Trim removes start and end characters &lt;= 32. 1363 * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"]) = -1
291 * To strip whitespace use {@link #strip(String)}.</p> 1364 * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
292 * 1365 * StringUtils.indexOfAny("zzabyycdxx", [""]) = 0
293 * <p>To trim your choice of characters, use the 1366 * StringUtils.indexOfAny("", [""]) = 0
294 * {@link #strip(String, String)} methods.</p> 1367 * StringUtils.indexOfAny("", ["a"]) = -1
295 * 1368 * </pre>
296 * <pre> 1369 *
297 * StringUtils.trim(null) = null 1370 * @param str the String to check, may be null
298 * StringUtils.trim("") = "" 1371 * @param searchStrs the Strings to search for, may be null
299 * StringUtils.trim(" ") = "" 1372 * @return the first index of any of the searchStrs in str, -1 if no match
300 * StringUtils.trim("abc") = "abc" 1373 */
301 * StringUtils.trim(" abc ") = "abc" 1374 public static int indexOfAny(String str, String[] searchStrs)
302 * </pre> 1375 {
303 * 1376 if ((str == null) || (searchStrs == null))
304 * @param str the String to be trimmed, may be null 1377 {
305 * @return the trimmed string, <code>null</code> if null String input 1378 return -1;
306 */ 1379 }
307 public static String trim(String str) { 1380 int sz = searchStrs.length;
308 return str == null ? null : str.trim(); 1381
309 } 1382 // String's can't have a MAX_VALUEth index.
310 1383 int ret = Integer.MAX_VALUE;
311 /** 1384
312 * <p>Removes control characters (char &lt;= 32) from both 1385 int tmp = 0;
313 * ends of this String returning <code>null</code> if the String is 1386 for (int i = 0; i < sz; i++)
314 * empty ("") after the trim or if it is <code>null</code>. 1387 {
315 * 1388 String search = searchStrs[i];
316 * <p>The String is trimmed using {@link String#trim()}. 1389 if (search == null)
317 * Trim removes start and end characters &lt;= 32. 1390 {
318 * To strip whitespace use {@link #stripToNull(String)}.</p> 1391 continue;
319 * 1392 }
320 * <pre> 1393 tmp = str.indexOf(search);
321 * StringUtils.trimToNull(null) = null 1394 if (tmp == -1)
322 * StringUtils.trimToNull("") = null 1395 {
323 * StringUtils.trimToNull(" ") = null 1396 continue;
324 * StringUtils.trimToNull("abc") = "abc" 1397 }
325 * StringUtils.trimToNull(" abc ") = "abc" 1398
326 * </pre> 1399 if (tmp < ret)
327 * 1400 {
328 * @param str the String to be trimmed, may be null 1401 ret = tmp;
329 * @return the trimmed String, 1402 }
330 * <code>null</code> if only chars &lt;= 32, empty or null String input 1403 }
331 * @since 2.0 1404
332 */ 1405 return (ret == Integer.MAX_VALUE) ? -1 : ret;
333 public static String trimToNull(String str) { 1406 }
334 String ts = trim(str); 1407
335 return isEmpty(ts) ? null : ts; 1408 /**
336 } 1409 * <p>Find the latest index of any of a set of potential substrings.</p>
337 1410 * <p/>
338 /** 1411 * <p>A <code>null</code> String will return <code>-1</code>.
339 * <p>Removes control characters (char &lt;= 32) from both 1412 * A <code>null</code> search array will return <code>-1</code>.
340 * ends of this String returning an empty String ("") if the String 1413 * A <code>null</code> or zero length search array entry will be ignored,
341 * is empty ("") after the trim or if it is <code>null</code>. 1414 * but a search array containing "" will return the length of <code>str</code>
342 * 1415 * if <code>str</code> is not null. This method uses {@link String#indexOf(Str ing)}</p>
343 * <p>The String is trimmed using {@link String#trim()}. 1416 * <p/>
344 * Trim removes start and end characters &lt;= 32. 1417 * <pre>
345 * To strip whitespace use {@link #stripToEmpty(String)}.</p> 1418 * StringUtils.lastIndexOfAny(null, *) = -1
346 * 1419 * StringUtils.lastIndexOfAny(*, null) = -1
347 * <pre> 1420 * StringUtils.lastIndexOfAny(*, []) = -1
348 * StringUtils.trimToEmpty(null) = "" 1421 * StringUtils.lastIndexOfAny(*, [null]) = -1
349 * StringUtils.trimToEmpty("") = "" 1422 * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
350 * StringUtils.trimToEmpty(" ") = "" 1423 * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
351 * StringUtils.trimToEmpty("abc") = "abc" 1424 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
352 * StringUtils.trimToEmpty(" abc ") = "abc" 1425 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
353 * </pre> 1426 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""]) = 10
354 * 1427 * </pre>
355 * @param str the String to be trimmed, may be null 1428 *
356 * @return the trimmed String, or an empty String if <code>null</code> input 1429 * @param str the String to check, may be null
357 * @since 2.0 1430 * @param searchStrs the Strings to search for, may be null
358 */ 1431 * @return the last index of any of the Strings, -1 if no match
359 public static String trimToEmpty(String str) { 1432 */
360 return str == null ? EMPTY : str.trim(); 1433 public static int lastIndexOfAny(String str, String[] searchStrs)
361 } 1434 {
362 1435 if ((str == null) || (searchStrs == null))
363 // Stripping 1436 {
364 //----------------------------------------------------------------------- 1437 return -1;
365 /** 1438 }
366 * <p>Strips whitespace from the start and end of a String.</p> 1439 int sz = searchStrs.length;
367 * 1440 int ret = -1;
368 * <p>This is similar to {@link #trim(String)} but removes whitespace. 1441 int tmp = 0;
369 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p> 1442 for (int i = 0; i < sz; i++)
370 * 1443 {
371 * <p>A <code>null</code> input String returns <code>null</code>.</p> 1444 String search = searchStrs[i];
372 * 1445 if (search == null)
373 * <pre> 1446 {
374 * StringUtils.strip(null) = null 1447 continue;
375 * StringUtils.strip("") = "" 1448 }
376 * StringUtils.strip(" ") = "" 1449 tmp = str.lastIndexOf(search);
377 * StringUtils.strip("abc") = "abc" 1450 if (tmp > ret)
378 * StringUtils.strip(" abc") = "abc" 1451 {
379 * StringUtils.strip("abc ") = "abc" 1452 ret = tmp;
380 * StringUtils.strip(" abc ") = "abc" 1453 }
381 * StringUtils.strip(" ab c ") = "ab c" 1454 }
382 * </pre> 1455 return ret;
383 * 1456 }
384 * @param str the String to remove whitespace from, may be null 1457
385 * @return the stripped String, <code>null</code> if null String input 1458 // Substring
386 */ 1459 //-----------------------------------------------------------------------
387 public static String strip(String str) { 1460
388 return strip(str, null); 1461 /**
389 } 1462 * <p>Gets a substring from the specified String avoiding exceptions.</p>
390 1463 * <p/>
391 /** 1464 * <p>A negative start position can be used to start <code>n</code>
392 * <p>Strips whitespace from the start and end of a String returning 1465 * characters from the end of the String.</p>
393 * <code>null</code> if the String is empty ("") after the strip.</p> 1466 * <p/>
394 * 1467 * <p>A <code>null</code> String will return <code>null</code>.
395 * <p>This is similar to {@link #trimToNull(String)} but removes whitespace. 1468 * An empty ("") String will return "".</p>
396 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p> 1469 * <p/>
397 * 1470 * <pre>
398 * <pre> 1471 * StringUtils.substring(null, *) = null
399 * StringUtils.stripToNull(null) = null 1472 * StringUtils.substring("", *) = ""
400 * StringUtils.stripToNull("") = null 1473 * StringUtils.substring("abc", 0) = "abc"
401 * StringUtils.stripToNull(" ") = null 1474 * StringUtils.substring("abc", 2) = "c"
402 * StringUtils.stripToNull("abc") = "abc" 1475 * StringUtils.substring("abc", 4) = ""
403 * StringUtils.stripToNull(" abc") = "abc" 1476 * StringUtils.substring("abc", -2) = "bc"
404 * StringUtils.stripToNull("abc ") = "abc" 1477 * StringUtils.substring("abc", -4) = "abc"
405 * StringUtils.stripToNull(" abc ") = "abc" 1478 * </pre>
406 * StringUtils.stripToNull(" ab c ") = "ab c" 1479 *
407 * </pre> 1480 * @param str the String to get the substring from, may be null
408 * 1481 * @param start the position to start from, negative means
409 * @param str the String to be stripped, may be null 1482 * count back from the end of the String by this many characters
410 * @return the stripped String, 1483 * @return substring from start position, <code>null</code> if null String inp ut
411 * <code>null</code> if whitespace, empty or null String input 1484 */
412 * @since 2.0 1485 public static String substring(String str, int start)
413 */ 1486 {
414 public static String stripToNull(String str) { 1487 if (str == null)
415 if (str == null) { 1488 {
416 return null; 1489 return null;
1490 }
1491
1492 // handle negatives, which means last n characters
1493 if (start < 0)
1494 {
1495 start = str.length() + start; // remember start is negative
1496 }
1497
1498 if (start < 0)
1499 {
1500 start = 0;
1501 }
1502 if (start > str.length())
1503 {
1504 return EMPTY;
1505 }
1506
1507 return str.substring(start);
1508 }
1509
1510 /**
1511 * <p>Gets a substring from the specified String avoiding exceptions.</p>
1512 * <p/>
1513 * <p>A negative start position can be used to start/end <code>n</code>
1514 * characters from the end of the String.</p>
1515 * <p/>
1516 * <p>The returned substring starts with the character in the <code>start</cod e>
1517 * position and ends before the <code>end</code> position. All position counti ng is
1518 * zero-based -- i.e., to start at the beginning of the string use
1519 * <code>start = 0</code>. Negative start and end positions can be used to
1520 * specify offsets relative to the end of the String.</p>
1521 * <p/>
1522 * <p>If <code>start</code> is not strictly to the left of <code>end</code>, " "
1523 * is returned.</p>
1524 * <p/>
1525 * <pre>
1526 * StringUtils.substring(null, *, *) = null
1527 * StringUtils.substring("", * , *) = "";
1528 * StringUtils.substring("abc", 0, 2) = "ab"
1529 * StringUtils.substring("abc", 2, 0) = ""
1530 * StringUtils.substring("abc", 2, 4) = "c"
1531 * StringUtils.substring("abc", 4, 6) = ""
1532 * StringUtils.substring("abc", 2, 2) = ""
1533 * StringUtils.substring("abc", -2, -1) = "b"
1534 * StringUtils.substring("abc", -4, 2) = "ab"
1535 * </pre>
1536 *
1537 * @param str the String to get the substring from, may be null
1538 * @param start the position to start from, negative means
1539 * count back from the end of the String by this many characters
1540 * @param end the position to end at (exclusive), negative means
1541 * count back from the end of the String by this many characters
1542 * @return substring from start position to end positon,
1543 * <code>null</code> if null String input
1544 */
1545 public static String substring(String str, int start, int end)
1546 {
1547 if (str == null)
1548 {
1549 return null;
1550 }
1551
1552 // handle negatives
1553 if (end < 0)
1554 {
1555 end = str.length() + end; // remember end is negative
1556 }
1557 if (start < 0)
1558 {
1559 start = str.length() + start; // remember start is negative
1560 }
1561
1562 // check length next
1563 if (end > str.length())
1564 {
1565 end = str.length();
1566 }
1567
1568 // if start is greater than end, return ""
1569 if (start > end)
1570 {
1571 return EMPTY;
1572 }
1573
1574 if (start < 0)
1575 {
1576 start = 0;
1577 }
1578 if (end < 0)
1579 {
1580 end = 0;
1581 }
1582
1583 return str.substring(start, end);
1584 }
1585
1586 // Left/Right/Mid
1587 //-----------------------------------------------------------------------
1588
1589 /**
1590 * <p>Gets the leftmost <code>len</code> characters of a String.</p>
1591 * <p/>
1592 * <p>If <code>len</code> characters are not available, or the
1593 * String is <code>null</code>, the String will be returned without
1594 * an exception. An exception is thrown if len is negative.</p>
1595 * <p/>
1596 * <pre>
1597 * StringUtils.left(null, *) = null
1598 * StringUtils.left(*, -ve) = ""
1599 * StringUtils.left("", *) = ""
1600 * StringUtils.left("abc", 0) = ""
1601 * StringUtils.left("abc", 2) = "ab"
1602 * StringUtils.left("abc", 4) = "abc"
1603 * </pre>
1604 *
1605 * @param str the String to get the leftmost characters from, may be null
1606 * @param len the length of the required String, must be zero or positive
1607 * @return the leftmost characters, <code>null</code> if null String input
1608 */
1609 public static String left(String str, int len)
1610 {
1611 if (str == null)
1612 {
1613 return null;
1614 }
1615 if (len < 0)
1616 {
1617 return EMPTY;
1618 }
1619 if (str.length() <= len)
1620 {
1621 return str;
1622 }
1623 return str.substring(0, len);
1624 }
1625
1626 /**
1627 * <p>Gets the rightmost <code>len</code> characters of a String.</p>
1628 * <p/>
1629 * <p>If <code>len</code> characters are not available, or the String
1630 * is <code>null</code>, the String will be returned without an
1631 * an exception. An exception is thrown if len is negative.</p>
1632 * <p/>
1633 * <pre>
1634 * StringUtils.right(null, *) = null
1635 * StringUtils.right(*, -ve) = ""
1636 * StringUtils.right("", *) = ""
1637 * StringUtils.right("abc", 0) = ""
1638 * StringUtils.right("abc", 2) = "bc"
1639 * StringUtils.right("abc", 4) = "abc"
1640 * </pre>
1641 *
1642 * @param str the String to get the rightmost characters from, may be null
1643 * @param len the length of the required String, must be zero or positive
1644 * @return the rightmost characters, <code>null</code> if null String input
1645 */
1646 public static String right(String str, int len)
1647 {
1648 if (str == null)
1649 {
1650 return null;
1651 }
1652 if (len < 0)
1653 {
1654 return EMPTY;
1655 }
1656 if (str.length() <= len)
1657 {
1658 return str;
1659 }
1660 return str.substring(str.length() - len);
1661 }
1662
1663 /**
1664 * <p>Gets <code>len</code> characters from the middle of a String.</p>
1665 * <p/>
1666 * <p>If <code>len</code> characters are not available, the remainder
1667 * of the String will be returned without an exception. If the
1668 * String is <code>null</code>, <code>null</code> will be returned.
1669 * An exception is thrown if len is negative.</p>
1670 * <p/>
1671 * <pre>
1672 * StringUtils.mid(null, *, *) = null
1673 * StringUtils.mid(*, *, -ve) = ""
1674 * StringUtils.mid("", 0, *) = ""
1675 * StringUtils.mid("abc", 0, 2) = "ab"
1676 * StringUtils.mid("abc", 0, 4) = "abc"
1677 * StringUtils.mid("abc", 2, 4) = "c"
1678 * StringUtils.mid("abc", 4, 2) = ""
1679 * StringUtils.mid("abc", -2, 2) = "ab"
1680 * </pre>
1681 *
1682 * @param str the String to get the characters from, may be null
1683 * @param pos the position to start from, negative treated as zero
1684 * @param len the length of the required String, must be zero or positive
1685 * @return the middle characters, <code>null</code> if null String input
1686 */
1687 public static String mid(String str, int pos, int len)
1688 {
1689 if (str == null)
1690 {
1691 return null;
1692 }
1693 if (len < 0 || pos > str.length())
1694 {
1695 return EMPTY;
1696 }
1697 if (pos < 0)
1698 {
1699 pos = 0;
1700 }
1701 if (str.length() <= (pos + len))
1702 {
1703 return str.substring(pos);
1704 }
1705 return str.substring(pos, pos + len);
1706 }
1707
1708 // SubStringAfter/SubStringBefore
1709 //-----------------------------------------------------------------------
1710
1711 /**
1712 * <p>Gets the substring before the first occurrence of a separator.
1713 * The separator is not returned.</p>
1714 * <p/>
1715 * <p>A <code>null</code> string input will return <code>null</code>.
1716 * An empty ("") string input will return the empty string.
1717 * A <code>null</code> separator will return the input string.</p>
1718 * <p/>
1719 * <pre>
1720 * StringUtils.substringBefore(null, *) = null
1721 * StringUtils.substringBefore("", *) = ""
1722 * StringUtils.substringBefore("abc", "a") = ""
1723 * StringUtils.substringBefore("abcba", "b") = "a"
1724 * StringUtils.substringBefore("abc", "c") = "ab"
1725 * StringUtils.substringBefore("abc", "d") = "abc"
1726 * StringUtils.substringBefore("abc", "") = ""
1727 * StringUtils.substringBefore("abc", null) = "abc"
1728 * </pre>
1729 *
1730 * @param str the String to get a substring from, may be null
1731 * @param separator the String to search for, may be null
1732 * @return the substring before the first occurrence of the separator,
1733 * <code>null</code> if null String input
1734 * @since 2.0
1735 */
1736 public static String substringBefore(String str, String separator)
1737 {
1738 if (isEmpty(str) || separator == null)
1739 {
1740 return str;
1741 }
1742 if (separator.length() == 0)
1743 {
1744 return EMPTY;
1745 }
1746 int pos = str.indexOf(separator);
1747 if (pos == -1)
1748 {
1749 return str;
1750 }
1751 return str.substring(0, pos);
1752 }
1753
1754 /**
1755 * <p>Gets the substring after the first occurrence of a separator.
1756 * The separator is not returned.</p>
1757 * <p/>
1758 * <p>A <code>null</code> string input will return <code>null</code>.
1759 * An empty ("") string input will return the empty string.
1760 * A <code>null</code> separator will return the empty string if the
1761 * input string is not <code>null</code>.</p>
1762 * <p/>
1763 * <pre>
1764 * StringUtils.substringAfter(null, *) = null
1765 * StringUtils.substringAfter("", *) = ""
1766 * StringUtils.substringAfter(*, null) = ""
1767 * StringUtils.substringAfter("abc", "a") = "bc"
1768 * StringUtils.substringAfter("abcba", "b") = "cba"
1769 * StringUtils.substringAfter("abc", "c") = ""
1770 * StringUtils.substringAfter("abc", "d") = ""
1771 * StringUtils.substringAfter("abc", "") = "abc"
1772 * </pre>
1773 *
1774 * @param str the String to get a substring from, may be null
1775 * @param separator the String to search for, may be null
1776 * @return the substring after the first occurrence of the separator,
1777 * <code>null</code> if null String input
1778 * @since 2.0
1779 */
1780 public static String substringAfter(String str, String separator)
1781 {
1782 if (isEmpty(str))
1783 {
1784 return str;
1785 }
1786 if (separator == null)
1787 {
1788 return EMPTY;
1789 }
1790 int pos = str.indexOf(separator);
1791 if (pos == -1)
1792 {
1793 return EMPTY;
1794 }
1795 return str.substring(pos + separator.length());
1796 }
1797
1798 /**
1799 * <p>Gets the substring before the last occurrence of a separator.
1800 * The separator is not returned.</p>
1801 * <p/>
1802 * <p>A <code>null</code> string input will return <code>null</code>.
1803 * An empty ("") string input will return the empty string.
1804 * An empty or <code>null</code> separator will return the input string.</p>
1805 * <p/>
1806 * <pre>
1807 * StringUtils.substringBeforeLast(null, *) = null
1808 * StringUtils.substringBeforeLast("", *) = ""
1809 * StringUtils.substringBeforeLast("abcba", "b") = "abc"
1810 * StringUtils.substringBeforeLast("abc", "c") = "ab"
1811 * StringUtils.substringBeforeLast("a", "a") = ""
1812 * StringUtils.substringBeforeLast("a", "z") = "a"
1813 * StringUtils.substringBeforeLast("a", null) = "a"
1814 * StringUtils.substringBeforeLast("a", "") = "a"
1815 * </pre>
1816 *
1817 * @param str the String to get a substring from, may be null
1818 * @param separator the String to search for, may be null
1819 * @return the substring before the last occurrence of the separator,
1820 * <code>null</code> if null String input
1821 * @since 2.0
1822 */
1823 public static String substringBeforeLast(String str, String separator)
1824 {
1825 if (isEmpty(str) || isEmpty(separator))
1826 {
1827 return str;
1828 }
1829 int pos = str.lastIndexOf(separator);
1830 if (pos == -1)
1831 {
1832 return str;
1833 }
1834 return str.substring(0, pos);
1835 }
1836
1837 /**
1838 * <p>Gets the substring after the last occurrence of a separator.
1839 * The separator is not returned.</p>
1840 * <p/>
1841 * <p>A <code>null</code> string input will return <code>null</code>.
1842 * An empty ("") string input will return the empty string.
1843 * An empty or <code>null</code> separator will return the empty string if
1844 * the input string is not <code>null</code>.</p>
1845 * <p/>
1846 * <pre>
1847 * StringUtils.substringAfterLast(null, *) = null
1848 * StringUtils.substringAfterLast("", *) = ""
1849 * StringUtils.substringAfterLast(*, "") = ""
1850 * StringUtils.substringAfterLast(*, null) = ""
1851 * StringUtils.substringAfterLast("abc", "a") = "bc"
1852 * StringUtils.substringAfterLast("abcba", "b") = "a"
1853 * StringUtils.substringAfterLast("abc", "c") = ""
1854 * StringUtils.substringAfterLast("a", "a") = ""
1855 * StringUtils.substringAfterLast("a", "z") = ""
1856 * </pre>
1857 *
1858 * @param str the String to get a substring from, may be null
1859 * @param separator the String to search for, may be null
1860 * @return the substring after the last occurrence of the separator,
1861 * <code>null</code> if null String input
1862 * @since 2.0
1863 */
1864 public static String substringAfterLast(String str, String separator)
1865 {
1866 if (isEmpty(str))
1867 {
1868 return str;
1869 }
1870 if (isEmpty(separator))
1871 {
1872 return EMPTY;
1873 }
1874 int pos = str.lastIndexOf(separator);
1875 if (pos == -1 || pos == (str.length() - separator.length()))
1876 {
1877 return EMPTY;
1878 }
1879 return str.substring(pos + separator.length());
1880 }
1881
1882 // Substring between
1883 //-----------------------------------------------------------------------
1884
1885 /**
1886 * <p>Gets the String that is nested in between two instances of the
1887 * same String.</p>
1888 * <p/>
1889 * <p>A <code>null</code> input String returns <code>null</code>.
1890 * A <code>null</code> tag returns <code>null</code>.</p>
1891 * <p/>
1892 * <pre>
1893 * StringUtils.substringBetween(null, *) = null
1894 * StringUtils.substringBetween("", "") = ""
1895 * StringUtils.substringBetween("", "tag") = null
1896 * StringUtils.substringBetween("tagabctag", null) = null
1897 * StringUtils.substringBetween("tagabctag", "") = ""
1898 * StringUtils.substringBetween("tagabctag", "tag") = "abc"
1899 * </pre>
1900 *
1901 * @param str the String containing the substring, may be null
1902 * @param tag the String before and after the substring, may be null
1903 * @return the substring, <code>null</code> if no match
1904 * @since 2.0
1905 */
1906 public static String substringBetween(String str, String tag)
1907 {
1908 return substringBetween(str, tag, tag);
1909 }
1910
1911 /**
1912 * <p>Gets the String that is nested in between two Strings.
1913 * Only the first match is returned.</p>
1914 * <p/>
1915 * <p>A <code>null</code> input String returns <code>null</code>.
1916 * A <code>null</code> open/close returns <code>null</code> (no match).
1917 * An empty ("") open and close returns an empty string.</p>
1918 * <p/>
1919 * <pre>
1920 * StringUtils.substringBetween("wx[b]yz", "[", "]") = "b"
1921 * StringUtils.substringBetween(null, *, *) = null
1922 * StringUtils.substringBetween(*, null, *) = null
1923 * StringUtils.substringBetween(*, *, null) = null
1924 * StringUtils.substringBetween("", "", "") = ""
1925 * StringUtils.substringBetween("", "", "]") = null
1926 * StringUtils.substringBetween("", "[", "]") = null
1927 * StringUtils.substringBetween("yabcz", "", "") = ""
1928 * StringUtils.substringBetween("yabcz", "y", "z") = "abc"
1929 * StringUtils.substringBetween("yabczyabcz", "y", "z") = "abc"
1930 * </pre>
1931 *
1932 * @param str the String containing the substring, may be null
1933 * @param open the String before the substring, may be null
1934 * @param close the String after the substring, may be null
1935 * @return the substring, <code>null</code> if no match
1936 * @since 2.0
1937 */
1938 public static String substringBetween(String str, String open, String close)
1939 {
1940 if (str == null || open == null || close == null)
1941 {
1942 return null;
1943 }
1944 int start = str.indexOf(open);
1945 if (start != -1)
1946 {
1947 int end = str.indexOf(close, start + open.length());
1948 if (end != -1)
1949 {
1950 return str.substring(start + open.length(), end);
1951 }
1952 }
1953 return null;
1954 }
1955
1956 // Joining
1957 //-----------------------------------------------------------------------
1958
1959 /**
1960 * <p>Concatenates elements of an array into a single String.
1961 * Null objects or empty strings within the array are represented by
1962 * empty strings.</p>
1963 * <p/>
1964 * <pre>
1965 * StringUtils.concatenate(null) = null
1966 * StringUtils.concatenate([]) = ""
1967 * StringUtils.concatenate([null]) = ""
1968 * StringUtils.concatenate(["a", "b", "c"]) = "abc"
1969 * StringUtils.concatenate([null, "", "a"]) = "a"
1970 * </pre>
1971 *
1972 * @param array the array of values to concatenate, may be null
1973 * @return the concatenated String, <code>null</code> if null array input
1974 * @deprecated Use the better named {@link #join(Object[])} instead.
1975 * Method will be removed in Commons Lang 3.0.
1976 */
1977 public static String concatenate(Object[] array)
1978 {
1979 return join(array, null);
1980 }
1981
1982 /**
1983 * <p>Joins the elements of the provided array into a single String
1984 * containing the provided list of elements.</p>
1985 * <p/>
1986 * <p>No separator is added to the joined String.
1987 * Null objects or empty strings within the array are represented by
1988 * empty strings.</p>
1989 * <p/>
1990 * <pre>
1991 * StringUtils.join(null) = null
1992 * StringUtils.join([]) = ""
1993 * StringUtils.join([null]) = ""
1994 * StringUtils.join(["a", "b", "c"]) = "abc"
1995 * StringUtils.join([null, "", "a"]) = "a"
1996 * </pre>
1997 *
1998 * @param array the array of values to join together, may be null
1999 * @return the joined String, <code>null</code> if null array input
2000 * @since 2.0
2001 */
2002 public static String join(Object[] array)
2003 {
2004 return join(array, null);
2005 }
2006
2007 /**
2008 * <p>Joins the elements of the provided array into a single String
2009 * containing the provided list of elements.</p>
2010 * <p/>
2011 * <p>No delimiter is added before or after the list.
2012 * Null objects or empty strings within the array are represented by
2013 * empty strings.</p>
2014 * <p/>
2015 * <pre>
2016 * StringUtils.join(null, *) = null
2017 * StringUtils.join([], *) = ""
2018 * StringUtils.join([null], *) = ""
2019 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
2020 * StringUtils.join(["a", "b", "c"], null) = "abc"
2021 * StringUtils.join([null, "", "a"], ';') = ";;a"
2022 * </pre>
2023 *
2024 * @param array the array of values to join together, may be null
2025 * @param separator the separator character to use
2026 * @return the joined String, <code>null</code> if null array input
2027 * @since 2.0
2028 */
2029 public static String join(Object[] array, char separator)
2030 {
2031 if (array == null)
2032 {
2033 return null;
2034 }
2035
2036 return join(array, separator, 0, array.length);
2037 }
2038
2039 /**
2040 * <p>Joins the elements of the provided array into a single String
2041 * containing the provided list of elements.</p>
2042 * <p/>
2043 * <p>No delimiter is added before or after the list.
2044 * Null objects or empty strings within the array are represented by
2045 * empty strings.</p>
2046 * <p/>
2047 * <pre>
2048 * StringUtils.join(null, *) = null
2049 * StringUtils.join([], *) = ""
2050 * StringUtils.join([null], *) = ""
2051 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
2052 * StringUtils.join(["a", "b", "c"], null) = "abc"
2053 * StringUtils.join([null, "", "a"], ';') = ";;a"
2054 * </pre>
2055 *
2056 * @param array the array of values to join together, may be null
2057 * @param separator the separator character to use
2058 * @param startIndex the first index to start joining from. It is
2059 * an error to pass in an end index past the end of the arra y
2060 * @param endIndex the index to stop joining from (exclusive). It is
2061 * an error to pass in an end index past the end of the arra y
2062 * @return the joined String, <code>null</code> if null array input
2063 * @since 2.0
2064 */
2065 public static String join(Object[] array, char separator, int startIndex, int endIndex)
2066 {
2067 if (array == null)
2068 {
2069 return null;
2070 }
2071 int bufSize = (endIndex - startIndex);
2072 if (bufSize <= 0)
2073 {
2074 return EMPTY;
2075 }
2076
2077 bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().l ength()) + 1);
2078 StringBuffer buf = new StringBuffer(bufSize);
2079
2080 for (int i = startIndex; i < endIndex; i++)
2081 {
2082 if (i > startIndex)
2083 {
2084 buf.append(separator);
2085 }
2086 if (array[i] != null)
2087 {
2088 buf.append(array[i]);
2089 }
2090 }
2091 return buf.toString();
2092 }
2093
2094
2095 /**
2096 * <p>Joins the elements of the provided array into a single String
2097 * containing the provided list of elements.</p>
2098 * <p/>
2099 * <p>No delimiter is added before or after the list.
2100 * A <code>null</code> separator is the same as an empty String ("").
2101 * Null objects or empty strings within the array are represented by
2102 * empty strings.</p>
2103 * <p/>
2104 * <pre>
2105 * StringUtils.join(null, *) = null
2106 * StringUtils.join([], *) = ""
2107 * StringUtils.join([null], *) = ""
2108 * StringUtils.join(["a", "b", "c"], "--") = "a--b--c"
2109 * StringUtils.join(["a", "b", "c"], null) = "abc"
2110 * StringUtils.join(["a", "b", "c"], "") = "abc"
2111 * StringUtils.join([null, "", "a"], ',') = ",,a"
2112 * </pre>
2113 *
2114 * @param array the array of values to join together, may be null
2115 * @param separator the separator character to use, null treated as ""
2116 * @return the joined String, <code>null</code> if null array input
2117 */
2118 public static String join(Object[] array, String separator)
2119 {
2120 if (array == null)
2121 {
2122 return null;
2123 }
2124 return join(array, separator, 0, array.length);
2125 }
2126
2127 /**
2128 * <p>Joins the elements of the provided array into a single String
2129 * containing the provided list of elements.</p>
2130 * <p/>
2131 * <p>No delimiter is added before or after the list.
2132 * A <code>null</code> separator is the same as an empty String ("").
2133 * Null objects or empty strings within the array are represented by
2134 * empty strings.</p>
2135 * <p/>
2136 * <pre>
2137 * StringUtils.join(null, *) = null
2138 * StringUtils.join([], *) = ""
2139 * StringUtils.join([null], *) = ""
2140 * StringUtils.join(["a", "b", "c"], "--") = "a--b--c"
2141 * StringUtils.join(["a", "b", "c"], null) = "abc"
2142 * StringUtils.join(["a", "b", "c"], "") = "abc"
2143 * StringUtils.join([null, "", "a"], ',') = ",,a"
2144 * </pre>
2145 *
2146 * @param array the array of values to join together, may be null
2147 * @param separator the separator character to use, null treated as ""
2148 * @param startIndex the first index to start joining from. It is
2149 * an error to pass in an end index past the end of the arra y
2150 * @param endIndex the index to stop joining from (exclusive). It is
2151 * an error to pass in an end index past the end of the arra y
2152 * @return the joined String, <code>null</code> if null array input
2153 */
2154 public static String join(Object[] array, String separator, int startIndex, in t endIndex)
2155 {
2156 if (array == null)
2157 {
2158 return null;
2159 }
2160 if (separator == null)
2161 {
2162 separator = EMPTY;
2163 }
2164
2165 // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + len(se parator))
2166 // (Assuming that all Strings are roughly equally long)
2167 int bufSize = (endIndex - startIndex);
2168 if (bufSize <= 0)
2169 {
2170 return EMPTY;
2171 }
2172
2173 bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString().l ength())
2174 + separator.length());
2175
2176 StringBuffer buf = new StringBuffer(bufSize);
2177
2178 for (int i = startIndex; i < endIndex; i++)
2179 {
2180 if (i > startIndex)
2181 {
2182 buf.append(separator);
2183 }
2184 if (array[i] != null)
2185 {
2186 buf.append(array[i]);
2187 }
2188 }
2189 return buf.toString();
2190 }
2191
2192 // Delete
2193 //-----------------------------------------------------------------------
2194
2195 /**
2196 * <p>Deletes all whitespaces from a String as defined by
2197 * {@link Character#isWhitespace(char)}.</p>
2198 * <p/>
2199 * <pre>
2200 * StringUtils.deleteWhitespace(null) = null
2201 * StringUtils.deleteWhitespace("") = ""
2202 * StringUtils.deleteWhitespace("abc") = "abc"
2203 * StringUtils.deleteWhitespace(" ab c ") = "abc"
2204 * </pre>
2205 *
2206 * @param str the String to delete whitespace from, may be null
2207 * @return the String without whitespaces, <code>null</code> if null String in put
2208 */
2209 public static String deleteWhitespace(String str)
2210 {
2211 if (isEmpty(str))
2212 {
2213 return str;
2214 }
2215 int sz = str.length();
2216 char[] chs = new char[sz];
2217 int count = 0;
2218 for (int i = 0; i < sz; i++)
2219 {
2220 if (!Character.isWhitespace(str.charAt(i)))
2221 {
2222 chs[count++] = str.charAt(i);
2223 }
2224 }
2225 if (count == sz)
2226 {
2227 return str;
2228 }
2229 return new String(chs, 0, count);
2230 }
2231
2232 // Remove
2233 //-----------------------------------------------------------------------
2234
2235 /**
2236 * <p>Removes a substring only if it is at the begining of a source string,
2237 * otherwise returns the source string.</p>
2238 * <p/>
2239 * <p>A <code>null</code> source string will return <code>null</code>.
2240 * An empty ("") source string will return the empty string.
2241 * A <code>null</code> search string will return the source string.</p>
2242 * <p/>
2243 * <pre>
2244 * StringUtils.removeStart(null, *) = null
2245 * StringUtils.removeStart("", *) = ""
2246 * StringUtils.removeStart(*, null) = *
2247 * StringUtils.removeStart("www.domain.com", "www.") = "domain.com"
2248 * StringUtils.removeStart("domain.com", "www.") = "domain.com"
2249 * StringUtils.removeStart("www.domain.com", "domain") = "www.domain.com"
2250 * StringUtils.removeStart("abc", "") = "abc"
2251 * </pre>
2252 *
2253 * @param str the source String to search, may be null
2254 * @param remove the String to search for and remove, may be null
2255 * @return the substring with the string removed if found,
2256 * <code>null</code> if null String input
2257 * @since 2.1
2258 */
2259 public static String removeStart(String str, String remove)
2260 {
2261 if (isEmpty(str) || isEmpty(remove))
2262 {
2263 return str;
2264 }
2265 if (str.startsWith(remove))
2266 {
2267 return str.substring(remove.length());
2268 }
2269 return str;
2270 }
2271
2272 /**
2273 * <p>Case insensitive removal of a substring if it is at the begining of a so urce string,
2274 * otherwise returns the source string.</p>
2275 * <p/>
2276 * <p>A <code>null</code> source string will return <code>null</code>.
2277 * An empty ("") source string will return the empty string.
2278 * A <code>null</code> search string will return the source string.</p>
2279 * <p/>
2280 * <pre>
2281 * StringUtils.removeStartIgnoreCase(null, *) = null
2282 * StringUtils.removeStartIgnoreCase("", *) = ""
2283 * StringUtils.removeStartIgnoreCase(*, null) = *
2284 * StringUtils.removeStartIgnoreCase("www.domain.com", "www.") = "domain.com "
2285 * StringUtils.removeStartIgnoreCase("www.domain.com", "WWW.") = "domain.com "
2286 * StringUtils.removeStartIgnoreCase("domain.com", "www.") = "domain.com "
2287 * StringUtils.removeStartIgnoreCase("www.domain.com", "domain") = "www.domain .com"
2288 * StringUtils.removeStartIgnoreCase("abc", "") = "abc"
2289 * </pre>
2290 *
2291 * @param str the source String to search, may be null
2292 * @param remove the String to search for (case insensitive) and remove, may b e null
2293 * @return the substring with the string removed if found,
2294 * <code>null</code> if null String input
2295 * @since 2.4
2296 */
2297 public static String removeStartIgnoreCase(String str, String remove)
2298 {
2299 if (isEmpty(str) || isEmpty(remove))
2300 {
2301 return str;
2302 }
2303 if (startsWithIgnoreCase(str, remove))
2304 {
2305 return str.substring(remove.length());
2306 }
2307 return str;
2308 }
2309
2310 /**
2311 * <p>Removes a substring only if it is at the end of a source string,
2312 * otherwise returns the source string.</p>
2313 * <p/>
2314 * <p>A <code>null</code> source string will return <code>null</code>.
2315 * An empty ("") source string will return the empty string.
2316 * A <code>null</code> search string will return the source string.</p>
2317 * <p/>
2318 * <pre>
2319 * StringUtils.removeEnd(null, *) = null
2320 * StringUtils.removeEnd("", *) = ""
2321 * StringUtils.removeEnd(*, null) = *
2322 * StringUtils.removeEnd("www.domain.com", ".com.") = "www.domain.com"
2323 * StringUtils.removeEnd("www.domain.com", ".com") = "www.domain"
2324 * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"
2325 * StringUtils.removeEnd("abc", "") = "abc"
2326 * </pre>
2327 *
2328 * @param str the source String to search, may be null
2329 * @param remove the String to search for and remove, may be null
2330 * @return the substring with the string removed if found,
2331 * <code>null</code> if null String input
2332 * @since 2.1
2333 */
2334 public static String removeEnd(String str, String remove)
2335 {
2336 if (isEmpty(str) || isEmpty(remove))
2337 {
2338 return str;
2339 }
2340 if (str.endsWith(remove))
2341 {
2342 return str.substring(0, str.length() - remove.length());
2343 }
2344 return str;
2345 }
2346
2347 /**
2348 * <p>Case insensitive removal of a substring if it is at the end of a source string,
2349 * otherwise returns the source string.</p>
2350 * <p/>
2351 * <p>A <code>null</code> source string will return <code>null</code>.
2352 * An empty ("") source string will return the empty string.
2353 * A <code>null</code> search string will return the source string.</p>
2354 * <p/>
2355 * <pre>
2356 * StringUtils.removeEnd(null, *) = null
2357 * StringUtils.removeEnd("", *) = ""
2358 * StringUtils.removeEnd(*, null) = *
2359 * StringUtils.removeEnd("www.domain.com", ".com.") = "www.domain.com."
2360 * StringUtils.removeEnd("www.domain.com", ".com") = "www.domain"
2361 * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"
2362 * StringUtils.removeEnd("abc", "") = "abc"
2363 * </pre>
2364 *
2365 * @param str the source String to search, may be null
2366 * @param remove the String to search for (case insensitive) and remove, may b e null
2367 * @return the substring with the string removed if found,
2368 * <code>null</code> if null String input
2369 * @since 2.4
2370 */
2371 public static String removeEndIgnoreCase(String str, String remove)
2372 {
2373 if (isEmpty(str) || isEmpty(remove))
2374 {
2375 return str;
2376 }
2377 if (endsWithIgnoreCase(str, remove))
2378 {
2379 return str.substring(0, str.length() - remove.length());
2380 }
2381 return str;
2382 }
2383
2384 /**
2385 * <p>Removes all occurrences of a substring from within the source string.</p >
2386 * <p/>
2387 * <p>A <code>null</code> source string will return <code>null</code>.
2388 * An empty ("") source string will return the empty string.
2389 * A <code>null</code> remove string will return the source string.
2390 * An empty ("") remove string will return the source string.</p>
2391 * <p/>
2392 * <pre>
2393 * StringUtils.remove(null, *) = null
2394 * StringUtils.remove("", *) = ""
2395 * StringUtils.remove(*, null) = *
2396 * StringUtils.remove(*, "") = *
2397 * StringUtils.remove("queued", "ue") = "qd"
2398 * StringUtils.remove("queued", "zz") = "queued"
2399 * </pre>
2400 *
2401 * @param str the source String to search, may be null
2402 * @param remove the String to search for and remove, may be null
2403 * @return the substring with the string removed if found,
2404 * <code>null</code> if null String input
2405 * @since 2.1
2406 */
2407 public static String remove(String str, String remove)
2408 {
2409 if (isEmpty(str) || isEmpty(remove))
2410 {
2411 return str;
2412 }
2413 return replace(str, remove, EMPTY, -1);
2414 }
2415
2416 /**
2417 * <p>Removes all occurrences of a character from within the source string.</p >
2418 * <p/>
2419 * <p>A <code>null</code> source string will return <code>null</code>.
2420 * An empty ("") source string will return the empty string.</p>
2421 * <p/>
2422 * <pre>
2423 * StringUtils.remove(null, *) = null
2424 * StringUtils.remove("", *) = ""
2425 * StringUtils.remove("queued", 'u') = "qeed"
2426 * StringUtils.remove("queued", 'z') = "queued"
2427 * </pre>
2428 *
2429 * @param str the source String to search, may be null
2430 * @param remove the char to search for and remove, may be null
2431 * @return the substring with the char removed if found,
2432 * <code>null</code> if null String input
2433 * @since 2.1
2434 */
2435 public static String remove(String str, char remove)
2436 {
2437 if (isEmpty(str) || str.indexOf(remove) == -1)
2438 {
2439 return str;
2440 }
2441 char[] chars = str.toCharArray();
2442 int pos = 0;
2443 for (int i = 0; i < chars.length; i++)
2444 {
2445 if (chars[i] != remove)
2446 {
2447 chars[pos++] = chars[i];
2448 }
2449 }
2450 return new String(chars, 0, pos);
2451 }
2452
2453 // Replacing
2454 //-----------------------------------------------------------------------
2455
2456 /**
2457 * <p>Replaces a String with another String inside a larger String, once.</p>
2458 * <p/>
2459 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
2460 * <p/>
2461 * <pre>
2462 * StringUtils.replaceOnce(null, *, *) = null
2463 * StringUtils.replaceOnce("", *, *) = ""
2464 * StringUtils.replaceOnce("any", null, *) = "any"
2465 * StringUtils.replaceOnce("any", *, null) = "any"
2466 * StringUtils.replaceOnce("any", "", *) = "any"
2467 * StringUtils.replaceOnce("aba", "a", null) = "aba"
2468 * StringUtils.replaceOnce("aba", "a", "") = "ba"
2469 * StringUtils.replaceOnce("aba", "a", "z") = "zba"
2470 * </pre>
2471 *
2472 * @param text text to search and replace in, may be null
2473 * @param searchString the String to search for, may be null
2474 * @param replacement the String to replace with, may be null
2475 * @return the text with any replacements processed,
2476 * <code>null</code> if null String input
2477 * @see #replace(String text, String searchString, String replacement, int max )
2478 */
2479 public static String replaceOnce(String text, String searchString, String repl acement)
2480 {
2481 return replace(text, searchString, replacement, 1);
2482 }
2483
2484 /**
2485 * <p>Replaces all occurrences of a String within another String.</p>
2486 * <p/>
2487 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
2488 * <p/>
2489 * <pre>
2490 * StringUtils.replace(null, *, *) = null
2491 * StringUtils.replace("", *, *) = ""
2492 * StringUtils.replace("any", null, *) = "any"
2493 * StringUtils.replace("any", *, null) = "any"
2494 * StringUtils.replace("any", "", *) = "any"
2495 * StringUtils.replace("aba", "a", null) = "aba"
2496 * StringUtils.replace("aba", "a", "") = "b"
2497 * StringUtils.replace("aba", "a", "z") = "zbz"
2498 * </pre>
2499 *
2500 * @param text text to search and replace in, may be null
2501 * @param searchString the String to search for, may be null
2502 * @param replacement the String to replace it with, may be null
2503 * @return the text with any replacements processed,
2504 * <code>null</code> if null String input
2505 * @see #replace(String text, String searchString, String replacement, int max )
2506 */
2507 public static String replace(String text, String searchString, String replacem ent)
2508 {
2509 return replace(text, searchString, replacement, -1);
2510 }
2511
2512 /**
2513 * <p>Replaces a String with another String inside a larger String,
2514 * for the first <code>max</code> values of the search String.</p>
2515 * <p/>
2516 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
2517 * <p/>
2518 * <pre>
2519 * StringUtils.replace(null, *, *, *) = null
2520 * StringUtils.replace("", *, *, *) = ""
2521 * StringUtils.replace("any", null, *, *) = "any"
2522 * StringUtils.replace("any", *, null, *) = "any"
2523 * StringUtils.replace("any", "", *, *) = "any"
2524 * StringUtils.replace("any", *, *, 0) = "any"
2525 * StringUtils.replace("abaa", "a", null, -1) = "abaa"
2526 * StringUtils.replace("abaa", "a", "", -1) = "b"
2527 * StringUtils.replace("abaa", "a", "z", 0) = "abaa"
2528 * StringUtils.replace("abaa", "a", "z", 1) = "zbaa"
2529 * StringUtils.replace("abaa", "a", "z", 2) = "zbza"
2530 * StringUtils.replace("abaa", "a", "z", -1) = "zbzz"
2531 * </pre>
2532 *
2533 * @param text text to search and replace in, may be null
2534 * @param searchString the String to search for, may be null
2535 * @param replacement the String to replace it with, may be null
2536 * @param max maximum number of values to replace, or <code>-1</code> if no maximum
2537 * @return the text with any replacements processed,
2538 * <code>null</code> if null String input
2539 */
2540 public static String replace(String text, String searchString, String replacem ent, int max)
2541 {
2542 if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0)
2543 {
2544 return text;
2545 }
2546 int start = 0;
2547 int end = text.indexOf(searchString, start);
2548 if (end == -1)
2549 {
2550 return text;
2551 }
2552 int replLength = searchString.length();
2553 int increase = replacement.length() - replLength;
2554 increase = (increase < 0 ? 0 : increase);
2555 increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
2556 StringBuffer buf = new StringBuffer(text.length() + increase);
2557 while (end != -1)
2558 {
2559 buf.append(text.substring(start, end)).append(replacement);
2560 start = end + replLength;
2561 if (--max == 0)
2562 {
2563 break;
2564 }
2565 end = text.indexOf(searchString, start);
2566 }
2567 buf.append(text.substring(start));
2568 return buf.toString();
2569 }
2570
2571 /**
2572 * <p>
2573 * Replaces all occurrences of Strings within another String.
2574 * </p>
2575 * <p/>
2576 * <p>
2577 * A <code>null</code> reference passed to this method is a no-op, or if
2578 * any "search string" or "string to replace" is null, that replace will be
2579 * ignored. This will not repeat. For repeating replaces, call the
2580 * overloaded method.
2581 * </p>
2582 * <p/>
2583 * <pre>
2584 * StringUtils.replaceEach(null, *, *) = null
2585 * StringUtils.replaceEach("", *, *) = ""
2586 * StringUtils.replaceEach("aba", null, null) = "aba"
2587 * StringUtils.replaceEach("aba", new String[0], null) = "aba"
2588 * StringUtils.replaceEach("aba", null, new String[0]) = "aba"
2589 * StringUtils.replaceEach("aba", new String[]{"a"}, null) = "aba"
2590 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}) = "b"
2591 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}) = " aba"
2592 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w" , "t"}) = "wcte"
2593 * (example of how it does not repeat)
2594 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "t"}) = "dcte"
2595 * </pre>
2596 *
2597 * @param text text to search and replace in, no-op if null
2598 * @param searchList the Strings to search for, no-op if null
2599 * @param replacementList the Strings to replace them with, no-op if null
2600 * @return the text with any replacements processed, <code>null</code> if
2601 * null String input
2602 * @throws IndexOutOfBoundsException if the lengths of the arrays are not the same (null is ok,
2603 * and/or size 0)
2604 * @since 2.4
2605 */
2606 public static String replaceEach(String text, String[] searchList, String[] re placementList)
2607 {
2608 return replaceEach(text, searchList, replacementList, false, 0);
2609 }
2610
2611 /**
2612 * <p>
2613 * Replaces all occurrences of Strings within another String.
2614 * </p>
2615 * <p/>
2616 * <p>
2617 * A <code>null</code> reference passed to this method is a no-op, or if
2618 * any "search string" or "string to replace" is null, that replace will be
2619 * ignored. This will not repeat. For repeating replaces, call the
2620 * overloaded method.
2621 * </p>
2622 * <p/>
2623 * <pre>
2624 * StringUtils.replaceEach(null, *, *, *) = null
2625 * StringUtils.replaceEach("", *, *, *) = ""
2626 * StringUtils.replaceEach("aba", null, null, *) = "aba"
2627 * StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
2628 * StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
2629 * StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
2630 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = " b"
2631 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
2632 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w" , "t"}, *) = "wcte"
2633 * (example of how it repeats)
2634 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "t"}, false) = "dcte"
2635 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "t"}, true) = "tcte"
2636 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "ab"}, true) = IllegalArgumentException
2637 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "ab"}, false) = "dcabe"
2638 * </pre>
2639 *
2640 * @param text text to search and replace in, no-op if null
2641 * @param searchList the Strings to search for, no-op if null
2642 * @param replacementList the Strings to replace them with, no-op if null
2643 * @return the text with any replacements processed, <code>null</code> if
2644 * null String input
2645 * @throws IllegalArgumentException if the search is repeating and there is a n endless loop due
2646 * to outputs of one being inputs to another
2647 * @throws IndexOutOfBoundsException if the lengths of the arrays are not the same (null is ok,
2648 * and/or size 0)
2649 * @since 2.4
2650 */
2651 public static String replaceEachRepeatedly(String text, String[] searchList, S tring[] replacementList)
2652 {
2653 // timeToLive should be 0 if not used or nothing to replace, else it's
2654 // the length of the replace array
2655 int timeToLive = searchList == null ? 0 : searchList.length;
2656 return replaceEach(text, searchList, replacementList, true, timeToLive);
2657 }
2658
2659 /**
2660 * <p>
2661 * Replaces all occurrences of Strings within another String.
2662 * </p>
2663 * <p/>
2664 * <p>
2665 * A <code>null</code> reference passed to this method is a no-op, or if
2666 * any "search string" or "string to replace" is null, that replace will be
2667 * ignored.
2668 * </p>
2669 * <p/>
2670 * <pre>
2671 * StringUtils.replaceEach(null, *, *, *) = null
2672 * StringUtils.replaceEach("", *, *, *) = ""
2673 * StringUtils.replaceEach("aba", null, null, *) = "aba"
2674 * StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
2675 * StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
2676 * StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
2677 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = " b"
2678 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
2679 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w" , "t"}, *) = "wcte"
2680 * (example of how it repeats)
2681 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "t"}, false) = "dcte"
2682 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "t"}, true) = "tcte"
2683 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d" , "ab"}, *) = IllegalArgumentException
2684 * </pre>
2685 *
2686 * @param text text to search and replace in, no-op if null
2687 * @param searchList the Strings to search for, no-op if null
2688 * @param replacementList the Strings to replace them with, no-op if null
2689 * @param repeat if true, then replace repeatedly
2690 * until there are no more possible replacements or tim eToLive < 0
2691 * @param timeToLive if less than 0 then there is a circular reference an d endless
2692 * loop
2693 * @return the text with any replacements processed, <code>null</code> if
2694 * null String input
2695 * @throws IllegalArgumentException if the search is repeating and there is a n endless loop due
2696 * to outputs of one being inputs to another
2697 * @throws IndexOutOfBoundsException if the lengths of the arrays are not the same (null is ok,
2698 * and/or size 0)
2699 * @since 2.4
2700 */
2701 private static String replaceEach(String text, String[] searchList, String[] r eplacementList,
2702 boolean repeat, int timeToLive)
2703 {
2704
2705 // mchyzer Performance note: This creates very few new objects (one major go al)
2706 // let me know if there are performance requests, we can create a harness to measure
2707
2708 if (text == null || text.length() == 0 || searchList == null ||
2709 searchList.length == 0 || replacementList == null || replacementList.lengt h == 0)
2710 {
2711 return text;
2712 }
2713
2714 // if recursing, this shouldnt be less than 0
2715 if (timeToLive < 0)
2716 {
2717 throw new IllegalStateException("TimeToLive of " + timeToLive + " is less than 0: " + text);
2718 }
2719
2720 int searchLength = searchList.length;
2721 int replacementLength = replacementList.length;
2722
2723 // make sure lengths are ok, these need to be equal
2724 if (searchLength != replacementLength)
2725 {
2726 throw new IllegalArgumentException("Search and Replace array lengths don't match: "
2727 + searchLength
2728 + " vs "
2729 + replacementLength);
2730 }
2731
2732 // keep track of which still have matches
2733 boolean[] noMoreMatchesForReplIndex = new boolean[searchLength];
2734
2735 // index on index that the match was found
2736 int textIndex = -1;
2737 int replaceIndex = -1;
2738 int tempIndex = -1;
2739
2740 // index of replace array that will replace the search string found
2741 // NOTE: logic duplicated below START
2742 for (int i = 0; i < searchLength; i++)
2743 {
2744 if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
2745 searchList[i].length() == 0 || replacementList[i] == null)
2746 {
2747 continue;
2748 }
2749 tempIndex = text.indexOf(searchList[i]);
2750
2751 // see if we need to keep searching for this
2752 if (tempIndex == -1)
2753 {
2754 noMoreMatchesForReplIndex[i] = true;
2755 } else
2756 {
2757 if (textIndex == -1 || tempIndex < textIndex)
2758 {
2759 textIndex = tempIndex;
2760 replaceIndex = i;
417 } 2761 }
418 str = strip(str, null); 2762 }
419 return str.length() == 0 ? null : str; 2763 }
420 } 2764 // NOTE: logic mostly below END
421 2765
422 /** 2766 // no search strings found, we are done
423 * <p>Strips whitespace from the start and end of a String returning 2767 if (textIndex == -1)
424 * an empty String if <code>null</code> input.</p> 2768 {
425 * 2769 return text;
426 * <p>This is similar to {@link #trimToEmpty(String)} but removes whitespace . 2770 }
427 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p> 2771
428 * 2772 int start = 0;
429 * <pre> 2773
430 * StringUtils.stripToEmpty(null) = "" 2774 // get a good guess on the size of the result buffer so it doesnt have to do uble if it goes over a bit
431 * StringUtils.stripToEmpty("") = "" 2775 int increase = 0;
432 * StringUtils.stripToEmpty(" ") = "" 2776
433 * StringUtils.stripToEmpty("abc") = "abc" 2777 // count the replacement text elements that are larger than their correspond ing text being replaced
434 * StringUtils.stripToEmpty(" abc") = "abc" 2778 for (int i = 0; i < searchList.length; i++)
435 * StringUtils.stripToEmpty("abc ") = "abc" 2779 {
436 * StringUtils.stripToEmpty(" abc ") = "abc" 2780 int greater = replacementList[i].length() - searchList[i].length();
437 * StringUtils.stripToEmpty(" ab c ") = "ab c" 2781 if (greater > 0)
438 * </pre> 2782 {
439 * 2783 increase += 3 * greater; // assume 3 matches
440 * @param str the String to be stripped, may be null 2784 }
441 * @return the trimmed String, or an empty String if <code>null</code> input 2785 }
442 * @since 2.0 2786 // have upper-bound at 20% increase, then let Java take over
443 */ 2787 increase = Math.min(increase, text.length() / 5);
444 public static String stripToEmpty(String str) { 2788
445 return str == null ? EMPTY : strip(str, null); 2789 StringBuffer buf = new StringBuffer(text.length() + increase);
446 } 2790
447 2791 while (textIndex != -1)
448 /** 2792 {
449 * <p>Strips any of a set of characters from the start and end of a String. 2793
450 * This is similar to {@link String#trim()} but allows the characters 2794 for (int i = start; i < textIndex; i++)
451 * to be stripped to be controlled.</p> 2795 {
452 * 2796 buf.append(text.charAt(i));
453 * <p>A <code>null</code> input String returns <code>null</code>. 2797 }
454 * An empty string ("") input returns the empty string.</p> 2798 buf.append(replacementList[replaceIndex]);
455 * 2799
456 * <p>If the stripChars String is <code>null</code>, whitespace is 2800 start = textIndex + searchList[replaceIndex].length();
457 * stripped as defined by {@link Character#isWhitespace(char)}. 2801
458 * Alternatively use {@link #strip(String)}.</p> 2802 textIndex = -1;
459 * 2803 replaceIndex = -1;
460 * <pre> 2804 tempIndex = -1;
461 * StringUtils.strip(null, *) = null 2805 // find the next earliest match
462 * StringUtils.strip("", *) = "" 2806 // NOTE: logic mostly duplicated above START
463 * StringUtils.strip("abc", null) = "abc" 2807 for (int i = 0; i < searchLength; i++)
464 * StringUtils.strip(" abc", null) = "abc" 2808 {
465 * StringUtils.strip("abc ", null) = "abc" 2809 if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
466 * StringUtils.strip(" abc ", null) = "abc" 2810 searchList[i].length() == 0 || replacementList[i] == null)
467 * StringUtils.strip(" abcyx", "xyz") = " abc" 2811 {
468 * </pre> 2812 continue;
469 *
470 * @param str the String to remove characters from, may be null
471 * @param stripChars the characters to remove, null treated as whitespace
472 * @return the stripped String, <code>null</code> if null String input
473 */
474 public static String strip(String str, String stripChars) {
475 if (isEmpty(str)) {
476 return str;
477 } 2813 }
478 str = stripStart(str, stripChars); 2814 tempIndex = text.indexOf(searchList[i], start);
479 return stripEnd(str, stripChars); 2815
480 } 2816 // see if we need to keep searching for this
481 2817 if (tempIndex == -1)
482 /** 2818 {
483 * <p>Strips any of a set of characters from the start of a String.</p> 2819 noMoreMatchesForReplIndex[i] = true;
484 * 2820 } else
485 * <p>A <code>null</code> input String returns <code>null</code>. 2821 {
486 * An empty string ("") input returns the empty string.</p> 2822 if (textIndex == -1 || tempIndex < textIndex)
487 * 2823 {
488 * <p>If the stripChars String is <code>null</code>, whitespace is 2824 textIndex = tempIndex;
489 * stripped as defined by {@link Character#isWhitespace(char)}.</p> 2825 replaceIndex = i;
490 * 2826 }
491 * <pre>
492 * StringUtils.stripStart(null, *) = null
493 * StringUtils.stripStart("", *) = ""
494 * StringUtils.stripStart("abc", "") = "abc"
495 * StringUtils.stripStart("abc", null) = "abc"
496 * StringUtils.stripStart(" abc", null) = "abc"
497 * StringUtils.stripStart("abc ", null) = "abc "
498 * StringUtils.stripStart(" abc ", null) = "abc "
499 * StringUtils.stripStart("yxabc ", "xyz") = "abc "
500 * </pre>
501 *
502 * @param str the String to remove characters from, may be null
503 * @param stripChars the characters to remove, null treated as whitespace
504 * @return the stripped String, <code>null</code> if null String input
505 */
506 public static String stripStart(String str, String stripChars) {
507 int strLen;
508 if (str == null || (strLen = str.length()) == 0) {
509 return str;
510 } 2827 }
511 int start = 0; 2828 }
512 if (stripChars == null) { 2829 // NOTE: logic duplicated above END
513 while ((start != strLen) && Character.isWhitespace(str.charAt(start) )) { 2830
514 start++; 2831 }
515 } 2832 int textLength = text.length();
516 } else if (stripChars.length() == 0) { 2833 for (int i = start; i < textLength; i++)
517 return str; 2834 {
518 } else { 2835 buf.append(text.charAt(i));
519 while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) ! = -1)) { 2836 }
520 start++; 2837 String result = buf.toString();
521 } 2838 if (!repeat)
2839 {
2840 return result;
2841 }
2842
2843 return replaceEach(result, searchList, replacementList, repeat, timeToLive - 1);
2844 }
2845
2846 // Replace, character based
2847 //-----------------------------------------------------------------------
2848
2849 /**
2850 * <p>Replaces all occurrences of a character in a String with another.
2851 * This is a null-safe version of {@link String#replace(char, char)}.</p>
2852 * <p/>
2853 * <p>A <code>null</code> string input returns <code>null</code>.
2854 * An empty ("") string input returns an empty string.</p>
2855 * <p/>
2856 * <pre>
2857 * StringUtils.replaceChars(null, *, *) = null
2858 * StringUtils.replaceChars("", *, *) = ""
2859 * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya"
2860 * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba"
2861 * </pre>
2862 *
2863 * @param str String to replace characters in, may be null
2864 * @param searchChar the character to search for, may be null
2865 * @param replaceChar the character to replace, may be null
2866 * @return modified String, <code>null</code> if null string input
2867 * @since 2.0
2868 */
2869 public static String replaceChars(String str, char searchChar, char replaceCha r)
2870 {
2871 if (str == null)
2872 {
2873 return null;
2874 }
2875 return str.replace(searchChar, replaceChar);
2876 }
2877
2878 /**
2879 * <p>Replaces multiple characters in a String in one go.
2880 * This method can also be used to delete characters.</p>
2881 * <p/>
2882 * <p>For example:<br />
2883 * <code>replaceChars(&quot;hello&quot;, &quot;ho&quot;, &quot;jy&quot;) = jel ly</code>.</p>
2884 * <p/>
2885 * <p>A <code>null</code> string input returns <code>null</code>.
2886 * An empty ("") string input returns an empty string.
2887 * A null or empty set of search characters returns the input string.</p>
2888 * <p/>
2889 * <p>The length of the search characters should normally equal the length
2890 * of the replace characters.
2891 * If the search characters is longer, then the extra search characters
2892 * are deleted.
2893 * If the search characters is shorter, then the extra replace characters
2894 * are ignored.</p>
2895 * <p/>
2896 * <pre>
2897 * StringUtils.replaceChars(null, *, *) = null
2898 * StringUtils.replaceChars("", *, *) = ""
2899 * StringUtils.replaceChars("abc", null, *) = "abc"
2900 * StringUtils.replaceChars("abc", "", *) = "abc"
2901 * StringUtils.replaceChars("abc", "b", null) = "ac"
2902 * StringUtils.replaceChars("abc", "b", "") = "ac"
2903 * StringUtils.replaceChars("abcba", "bc", "yz") = "ayzya"
2904 * StringUtils.replaceChars("abcba", "bc", "y") = "ayya"
2905 * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya"
2906 * </pre>
2907 *
2908 * @param str String to replace characters in, may be null
2909 * @param searchChars a set of characters to search for, may be null
2910 * @param replaceChars a set of characters to replace, may be null
2911 * @return modified String, <code>null</code> if null string input
2912 * @since 2.0
2913 */
2914 public static String replaceChars(String str, String searchChars, String repla ceChars)
2915 {
2916 if (isEmpty(str) || isEmpty(searchChars))
2917 {
2918 return str;
2919 }
2920 if (replaceChars == null)
2921 {
2922 replaceChars = EMPTY;
2923 }
2924 boolean modified = false;
2925 int replaceCharsLength = replaceChars.length();
2926 int strLength = str.length();
2927 StringBuffer buf = new StringBuffer(strLength);
2928 for (int i = 0; i < strLength; i++)
2929 {
2930 char ch = str.charAt(i);
2931 int index = searchChars.indexOf(ch);
2932 if (index >= 0)
2933 {
2934 modified = true;
2935 if (index < replaceCharsLength)
2936 {
2937 buf.append(replaceChars.charAt(index));
522 } 2938 }
523 return str.substring(start); 2939 } else
524 } 2940 {
525 2941 buf.append(ch);
526 /** 2942 }
527 * <p>Strips any of a set of characters from the end of a String.</p> 2943 }
528 * 2944 if (modified)
529 * <p>A <code>null</code> input String returns <code>null</code>. 2945 {
530 * An empty string ("") input returns the empty string.</p> 2946 return buf.toString();
531 * 2947 }
532 * <p>If the stripChars String is <code>null</code>, whitespace is 2948 return str;
533 * stripped as defined by {@link Character#isWhitespace(char)}.</p> 2949 }
534 * 2950
535 * <pre> 2951 // Overlay
536 * StringUtils.stripEnd(null, *) = null 2952 //-----------------------------------------------------------------------
537 * StringUtils.stripEnd("", *) = "" 2953
538 * StringUtils.stripEnd("abc", "") = "abc" 2954 /**
539 * StringUtils.stripEnd("abc", null) = "abc" 2955 * <p>Overlays part of a String with another String.</p>
540 * StringUtils.stripEnd(" abc", null) = " abc" 2956 * <p/>
541 * StringUtils.stripEnd("abc ", null) = "abc" 2957 * <pre>
542 * StringUtils.stripEnd(" abc ", null) = " abc" 2958 * StringUtils.overlayString(null, *, *, *) = NullPointerException
543 * StringUtils.stripEnd(" abcyx", "xyz") = " abc" 2959 * StringUtils.overlayString(*, null, *, *) = NullPointerException
544 * </pre> 2960 * StringUtils.overlayString("", "abc", 0, 0) = "abc"
545 * 2961 * StringUtils.overlayString("abcdef", null, 2, 4) = "abef"
546 * @param str the String to remove characters from, may be null 2962 * StringUtils.overlayString("abcdef", "", 2, 4) = "abef"
547 * @param stripChars the characters to remove, null treated as whitespace 2963 * StringUtils.overlayString("abcdef", "zzzz", 2, 4) = "abzzzzef"
548 * @return the stripped String, <code>null</code> if null String input 2964 * StringUtils.overlayString("abcdef", "zzzz", 4, 2) = "abcdzzzzcdef"
549 */ 2965 * StringUtils.overlayString("abcdef", "zzzz", -1, 4) = IndexOutOfBoundsExcept ion
550 public static String stripEnd(String str, String stripChars) { 2966 * StringUtils.overlayString("abcdef", "zzzz", 2, 8) = IndexOutOfBoundsExcept ion
551 int end; 2967 * </pre>
552 if (str == null || (end = str.length()) == 0) { 2968 *
553 return str; 2969 * @param text the String to do overlaying in, may be null
2970 * @param overlay the String to overlay, may be null
2971 * @param start the position to start overlaying at, must be valid
2972 * @param end the position to stop overlaying before, must be valid
2973 * @return overlayed String, <code>null</code> if null String input
2974 * @throws NullPointerException if text or overlay is null
2975 * @throws IndexOutOfBoundsException if either position is invalid
2976 * @deprecated Use better named {@link #overlay(String, String, int, int)} ins tead.
2977 * Method will be removed in Commons Lang 3.0.
2978 */
2979 public static String overlayString(String text, String overlay, int start, int end)
2980 {
2981 return new StringBuffer(start + overlay.length() + text.length() - end + 1)
2982 .append(text.substring(0, start))
2983 .append(overlay)
2984 .append(text.substring(end))
2985 .toString();
2986 }
2987
2988 /**
2989 * <p>Overlays part of a String with another String.</p>
2990 * <p/>
2991 * <p>A <code>null</code> string input returns <code>null</code>.
2992 * A negative index is treated as zero.
2993 * An index greater than the string length is treated as the string length.
2994 * The start index is always the smaller of the two indices.</p>
2995 * <p/>
2996 * <pre>
2997 * StringUtils.overlay(null, *, *, *) = null
2998 * StringUtils.overlay("", "abc", 0, 0) = "abc"
2999 * StringUtils.overlay("abcdef", null, 2, 4) = "abef"
3000 * StringUtils.overlay("abcdef", "", 2, 4) = "abef"
3001 * StringUtils.overlay("abcdef", "", 4, 2) = "abef"
3002 * StringUtils.overlay("abcdef", "zzzz", 2, 4) = "abzzzzef"
3003 * StringUtils.overlay("abcdef", "zzzz", 4, 2) = "abzzzzef"
3004 * StringUtils.overlay("abcdef", "zzzz", -1, 4) = "zzzzef"
3005 * StringUtils.overlay("abcdef", "zzzz", 2, 8) = "abzzzz"
3006 * StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
3007 * StringUtils.overlay("abcdef", "zzzz", 8, 10) = "abcdefzzzz"
3008 * </pre>
3009 *
3010 * @param str the String to do overlaying in, may be null
3011 * @param overlay the String to overlay, may be null
3012 * @param start the position to start overlaying at
3013 * @param end the position to stop overlaying before
3014 * @return overlayed String, <code>null</code> if null String input
3015 * @since 2.0
3016 */
3017 public static String overlay(String str, String overlay, int start, int end)
3018 {
3019 if (str == null)
3020 {
3021 return null;
3022 }
3023 if (overlay == null)
3024 {
3025 overlay = EMPTY;
3026 }
3027 int len = str.length();
3028 if (start < 0)
3029 {
3030 start = 0;
3031 }
3032 if (start > len)
3033 {
3034 start = len;
3035 }
3036 if (end < 0)
3037 {
3038 end = 0;
3039 }
3040 if (end > len)
3041 {
3042 end = len;
3043 }
3044 if (start > end)
3045 {
3046 int temp = start;
3047 start = end;
3048 end = temp;
3049 }
3050 return new StringBuffer(len + start - end + overlay.length() + 1)
3051 .append(str.substring(0, start))
3052 .append(overlay)
3053 .append(str.substring(end))
3054 .toString();
3055 }
3056
3057 // Chomping
3058 //-----------------------------------------------------------------------
3059
3060 /**
3061 * <p>Removes one newline from end of a String if it's there,
3062 * otherwise leave it alone. A newline is &quot;<code>\n</code>&quot;,
3063 * &quot;<code>\r</code>&quot;, or &quot;<code>\r\n</code>&quot;.</p>
3064 * <p/>
3065 * <p>NOTE: This method changed in 2.0.
3066 * It now more closely matches Perl chomp.</p>
3067 * <p/>
3068 * <pre>
3069 * StringUtils.chomp(null) = null
3070 * StringUtils.chomp("") = ""
3071 * StringUtils.chomp("abc \r") = "abc "
3072 * StringUtils.chomp("abc\n") = "abc"
3073 * StringUtils.chomp("abc\r\n") = "abc"
3074 * StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
3075 * StringUtils.chomp("abc\n\r") = "abc\n"
3076 * StringUtils.chomp("abc\n\rabc") = "abc\n\rabc"
3077 * StringUtils.chomp("\r") = ""
3078 * StringUtils.chomp("\n") = ""
3079 * StringUtils.chomp("\r\n") = ""
3080 * </pre>
3081 *
3082 * @param str the String to chomp a newline from, may be null
3083 * @return String without newline, <code>null</code> if null String input
3084 */
3085 public static String chomp(String str)
3086 {
3087 if (isEmpty(str))
3088 {
3089 return str;
3090 }
3091
3092 if (str.length() == 1)
3093 {
3094 char ch = str.charAt(0);
3095 if (ch == CharUtils.CR || ch == CharUtils.LF)
3096 {
3097 return EMPTY;
3098 }
3099 return str;
3100 }
3101
3102 int lastIdx = str.length() - 1;
3103 char last = str.charAt(lastIdx);
3104
3105 if (last == CharUtils.LF)
3106 {
3107 if (str.charAt(lastIdx - 1) == CharUtils.CR)
3108 {
3109 lastIdx--;
3110 }
3111 } else if (last != CharUtils.CR)
3112 {
3113 lastIdx++;
3114 }
3115 return str.substring(0, lastIdx);
3116 }
3117
3118 /**
3119 * <p>Removes <code>separator</code> from the end of
3120 * <code>str</code> if it's there, otherwise leave it alone.</p>
3121 * <p/>
3122 * <p>NOTE: This method changed in version 2.0.
3123 * It now more closely matches Perl chomp.
3124 * For the previous behavior, use {@link #substringBeforeLast(String, String)} .
3125 * This method uses {@link String#endsWith(String)}.</p>
3126 * <p/>
3127 * <pre>
3128 * StringUtils.chomp(null, *) = null
3129 * StringUtils.chomp("", *) = ""
3130 * StringUtils.chomp("foobar", "bar") = "foo"
3131 * StringUtils.chomp("foobar", "baz") = "foobar"
3132 * StringUtils.chomp("foo", "foo") = ""
3133 * StringUtils.chomp("foo ", "foo") = "foo "
3134 * StringUtils.chomp(" foo", "foo") = " "
3135 * StringUtils.chomp("foo", "foooo") = "foo"
3136 * StringUtils.chomp("foo", "") = "foo"
3137 * StringUtils.chomp("foo", null) = "foo"
3138 * </pre>
3139 *
3140 * @param str the String to chomp from, may be null
3141 * @param separator separator String, may be null
3142 * @return String without trailing separator, <code>null</code> if null String input
3143 */
3144 public static String chomp(String str, String separator)
3145 {
3146 if (isEmpty(str) || separator == null)
3147 {
3148 return str;
3149 }
3150 if (str.endsWith(separator))
3151 {
3152 return str.substring(0, str.length() - separator.length());
3153 }
3154 return str;
3155 }
3156
3157 /**
3158 * <p>Remove any &quot;\n&quot; if and only if it is at the end
3159 * of the supplied String.</p>
3160 *
3161 * @param str the String to chomp from, must not be null
3162 * @return String without chomped ending
3163 * @throws NullPointerException if str is <code>null</code>
3164 * @deprecated Use {@link #chomp(String)} instead.
3165 * Method will be removed in Commons Lang 3.0.
3166 */
3167 public static String chompLast(String str)
3168 {
3169 return chompLast(str, "\n");
3170 }
3171
3172 /**
3173 * <p>Remove a value if and only if the String ends with that value.</p>
3174 *
3175 * @param str the String to chomp from, must not be null
3176 * @param sep the String to chomp, must not be null
3177 * @return String without chomped ending
3178 * @throws NullPointerException if str or sep is <code>null</code>
3179 * @deprecated Use {@link #chomp(String, String)} instead.
3180 * Method will be removed in Commons Lang 3.0.
3181 */
3182 public static String chompLast(String str, String sep)
3183 {
3184 if (str.length() == 0)
3185 {
3186 return str;
3187 }
3188 String sub = str.substring(str.length() - sep.length());
3189 if (sep.equals(sub))
3190 {
3191 return str.substring(0, str.length() - sep.length());
3192 }
3193 return str;
3194 }
3195
3196 /**
3197 * <p>Remove everything and return the last value of a supplied String, and
3198 * everything after it from a String.</p>
3199 *
3200 * @param str the String to chomp from, must not be null
3201 * @param sep the String to chomp, must not be null
3202 * @return String chomped
3203 * @throws NullPointerException if str or sep is <code>null</code>
3204 * @deprecated Use {@link #substringAfterLast(String, String)} instead
3205 * (although this doesn't include the separator)
3206 * Method will be removed in Commons Lang 3.0.
3207 */
3208 public static String getChomp(String str, String sep)
3209 {
3210 int idx = str.lastIndexOf(sep);
3211 if (idx == str.length() - sep.length())
3212 {
3213 return sep;
3214 } else if (idx != -1)
3215 {
3216 return str.substring(idx);
3217 } else
3218 {
3219 return EMPTY;
3220 }
3221 }
3222
3223 /**
3224 * <p>Remove the first value of a supplied String, and everything before it
3225 * from a String.</p>
3226 *
3227 * @param str the String to chomp from, must not be null
3228 * @param sep the String to chomp, must not be null
3229 * @return String without chomped beginning
3230 * @throws NullPointerException if str or sep is <code>null</code>
3231 * @deprecated Use {@link #substringAfter(String, String)} instead.
3232 * Method will be removed in Commons Lang 3.0.
3233 */
3234 public static String prechomp(String str, String sep)
3235 {
3236 int idx = str.indexOf(sep);
3237 if (idx == -1)
3238 {
3239 return str;
3240 }
3241 return str.substring(idx + sep.length());
3242 }
3243
3244 /**
3245 * <p>Remove and return everything before the first value of a
3246 * supplied String from another String.</p>
3247 *
3248 * @param str the String to chomp from, must not be null
3249 * @param sep the String to chomp, must not be null
3250 * @return String prechomped
3251 * @throws NullPointerException if str or sep is <code>null</code>
3252 * @deprecated Use {@link #substringBefore(String, String)} instead
3253 * (although this doesn't include the separator).
3254 * Method will be removed in Commons Lang 3.0.
3255 */
3256 public static String getPrechomp(String str, String sep)
3257 {
3258 int idx = str.indexOf(sep);
3259 if (idx == -1)
3260 {
3261 return EMPTY;
3262 }
3263 return str.substring(0, idx + sep.length());
3264 }
3265
3266 // Chopping
3267 //-----------------------------------------------------------------------
3268
3269 /**
3270 * <p>Remove the last character from a String.</p>
3271 * <p/>
3272 * <p>If the String ends in <code>\r\n</code>, then remove both
3273 * of them.</p>
3274 * <p/>
3275 * <pre>
3276 * StringUtils.chop(null) = null
3277 * StringUtils.chop("") = ""
3278 * StringUtils.chop("abc \r") = "abc "
3279 * StringUtils.chop("abc\n") = "abc"
3280 * StringUtils.chop("abc\r\n") = "abc"
3281 * StringUtils.chop("abc") = "ab"
3282 * StringUtils.chop("abc\nabc") = "abc\nab"
3283 * StringUtils.chop("a") = ""
3284 * StringUtils.chop("\r") = ""
3285 * StringUtils.chop("\n") = ""
3286 * StringUtils.chop("\r\n") = ""
3287 * </pre>
3288 *
3289 * @param str the String to chop last character from, may be null
3290 * @return String without last character, <code>null</code> if null String inp ut
3291 */
3292 public static String chop(String str)
3293 {
3294 if (str == null)
3295 {
3296 return null;
3297 }
3298 int strLen = str.length();
3299 if (strLen < 2)
3300 {
3301 return EMPTY;
3302 }
3303 int lastIdx = strLen - 1;
3304 String ret = str.substring(0, lastIdx);
3305 char last = str.charAt(lastIdx);
3306 if (last == CharUtils.LF)
3307 {
3308 if (ret.charAt(lastIdx - 1) == CharUtils.CR)
3309 {
3310 return ret.substring(0, lastIdx - 1);
3311 }
3312 }
3313 return ret;
3314 }
3315
3316 /**
3317 * <p>Removes <code>\n</code> from end of a String if it's there.
3318 * If a <code>\r</code> precedes it, then remove that too.</p>
3319 *
3320 * @param str the String to chop a newline from, must not be null
3321 * @return String without newline
3322 * @throws NullPointerException if str is <code>null</code>
3323 * @deprecated Use {@link #chomp(String)} instead.
3324 * Method will be removed in Commons Lang 3.0.
3325 */
3326 public static String chopNewline(String str)
3327 {
3328 int lastIdx = str.length() - 1;
3329 if (lastIdx <= 0)
3330 {
3331 return EMPTY;
3332 }
3333 char last = str.charAt(lastIdx);
3334 if (last == CharUtils.LF)
3335 {
3336 if (str.charAt(lastIdx - 1) == CharUtils.CR)
3337 {
3338 lastIdx--;
3339 }
3340 } else
3341 {
3342 lastIdx++;
3343 }
3344 return str.substring(0, lastIdx);
3345 }
3346
3347 // Conversion
3348 //-----------------------------------------------------------------------
3349
3350 /**
3351 * <p>Escapes any values it finds into their String form.</p>
3352 * <p/>
3353 * <p>So a tab becomes the characters <code>'\\'</code> and
3354 * <code>'t'</code>.</p>
3355 * <p/>
3356 * <p>As of Lang 2.0, this calls {@link StringEscapeUtils#escapeJava(String)}
3357 * behind the scenes.
3358 * </p>
3359 *
3360 * @param str String to escape values in
3361 * @return String with escaped values
3362 * @throws NullPointerException if str is <code>null</code>
3363 * @see StringEscapeUtils#escapeJava(java.lang.String)
3364 * @deprecated Use {@link StringEscapeUtils#escapeJava(String)}
3365 * This method will be removed in Commons Lang 3.0
3366 */
3367 public static String escape(String str)
3368 {
3369 return StringEscapeUtils.escapeJava(str);
3370 }
3371
3372 // Padding
3373 //-----------------------------------------------------------------------
3374
3375 /**
3376 * <p>Repeat a String <code>repeat</code> times to form a
3377 * new String.</p>
3378 * <p/>
3379 * <pre>
3380 * StringUtils.repeat(null, 2) = null
3381 * StringUtils.repeat("", 0) = ""
3382 * StringUtils.repeat("", 2) = ""
3383 * StringUtils.repeat("a", 3) = "aaa"
3384 * StringUtils.repeat("ab", 2) = "abab"
3385 * StringUtils.repeat("a", -2) = ""
3386 * </pre>
3387 *
3388 * @param str the String to repeat, may be null
3389 * @param repeat number of times to repeat str, negative treated as zero
3390 * @return a new String consisting of the original String repeated,
3391 * <code>null</code> if null String input
3392 */
3393 public static String repeat(String str, int repeat)
3394 {
3395 // Performance tuned for 2.0 (JDK1.4)
3396
3397 if (str == null)
3398 {
3399 return null;
3400 }
3401 if (repeat <= 0)
3402 {
3403 return EMPTY;
3404 }
3405 int inputLength = str.length();
3406 if (repeat == 1 || inputLength == 0)
3407 {
3408 return str;
3409 }
3410 if (inputLength == 1 && repeat <= PAD_LIMIT)
3411 {
3412 return padding(repeat, str.charAt(0));
3413 }
3414
3415 int outputLength = inputLength * repeat;
3416 switch (inputLength)
3417 {
3418 case 1:
3419 char ch = str.charAt(0);
3420 char[] output1 = new char[outputLength];
3421 for (int i = repeat - 1; i >= 0; i--)
3422 {
3423 output1[i] = ch;
554 } 3424 }
555 3425 return new String(output1);
556 if (stripChars == null) { 3426 case 2:
557 while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) { 3427 char ch0 = str.charAt(0);
558 end--; 3428 char ch1 = str.charAt(1);
559 } 3429 char[] output2 = new char[outputLength];
560 } else if (stripChars.length() == 0) { 3430 for (int i = repeat * 2 - 2; i >= 0; i--, i--)
561 return str; 3431 {
562 } else { 3432 output2[i] = ch0;
563 while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != -1) ) { 3433 output2[i + 1] = ch1;
564 end--;
565 }
566 } 3434 }
567 return str.substring(0, end); 3435 return new String(output2);
568 } 3436 default:
569 3437 StringBuffer buf = new StringBuffer(outputLength);
570 // StripAll 3438 for (int i = 0; i < repeat; i++)
571 //----------------------------------------------------------------------- 3439 {
572 /** 3440 buf.append(str);
573 * <p>Strips whitespace from the start and end of every String in an array.
574 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
575 *
576 * <p>A new array is returned each time, except for length zero.
577 * A <code>null</code> array will return <code>null</code>.
578 * An empty array will return itself.
579 * A <code>null</code> array entry will be ignored.</p>
580 *
581 * <pre>
582 * StringUtils.stripAll(null) = null
583 * StringUtils.stripAll([]) = []
584 * StringUtils.stripAll(["abc", " abc"]) = ["abc", "abc"]
585 * StringUtils.stripAll(["abc ", null]) = ["abc", null]
586 * </pre>
587 *
588 * @param strs the array to remove whitespace from, may be null
589 * @return the stripped Strings, <code>null</code> if null array input
590 */
591 public static String[] stripAll(String[] strs) {
592 return stripAll(strs, null);
593 }
594
595 /**
596 * <p>Strips any of a set of characters from the start and end of every
597 * String in an array.</p>
598 * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
599 *
600 * <p>A new array is returned each time, except for length zero.
601 * A <code>null</code> array will return <code>null</code>.
602 * An empty array will return itself.
603 * A <code>null</code> array entry will be ignored.
604 * A <code>null</code> stripChars will strip whitespace as defined by
605 * {@link Character#isWhitespace(char)}.</p>
606 *
607 * <pre>
608 * StringUtils.stripAll(null, *) = null
609 * StringUtils.stripAll([], *) = []
610 * StringUtils.stripAll(["abc", " abc"], null) = ["abc", "abc"]
611 * StringUtils.stripAll(["abc ", null], null) = ["abc", null]
612 * StringUtils.stripAll(["abc ", null], "yz") = ["abc ", null]
613 * StringUtils.stripAll(["yabcz", null], "yz") = ["abc", null]
614 * </pre>
615 *
616 * @param strs the array to remove characters from, may be null
617 * @param stripChars the characters to remove, null treated as whitespace
618 * @return the stripped Strings, <code>null</code> if null array input
619 */
620 public static String[] stripAll(String[] strs, String stripChars) {
621 int strsLen;
622 if (strs == null || (strsLen = strs.length) == 0) {
623 return strs;
624 }
625 String[] newArr = new String[strsLen];
626 for (int i = 0; i < strsLen; i++) {
627 newArr[i] = strip(strs[i], stripChars);
628 }
629 return newArr;
630 }
631
632 // Equals
633 //-----------------------------------------------------------------------
634 /**
635 * <p>Compares two Strings, returning <code>true</code> if they are equal.</ p>
636 *
637 * <p><code>null</code>s are handled without exceptions. Two <code>null</cod e>
638 * references are considered to be equal. The comparison is case sensitive.< /p>
639 *
640 * <pre>
641 * StringUtils.equals(null, null) = true
642 * StringUtils.equals(null, "abc") = false
643 * StringUtils.equals("abc", null) = false
644 * StringUtils.equals("abc", "abc") = true
645 * StringUtils.equals("abc", "ABC") = false
646 * </pre>
647 *
648 * @see java.lang.String#equals(Object)
649 * @param str1 the first String, may be null
650 * @param str2 the second String, may be null
651 * @return <code>true</code> if the Strings are equal, case sensitive, or
652 * both <code>null</code>
653 */
654 public static boolean equals(String str1, String str2) {
655 return str1 == null ? str2 == null : str1.equals(str2);
656 }
657
658 /**
659 * <p>Compares two Strings, returning <code>true</code> if they are equal ig noring
660 * the case.</p>
661 *
662 * <p><code>null</code>s are handled without exceptions. Two <code>null</cod e>
663 * references are considered equal. Comparison is case insensitive.</p>
664 *
665 * <pre>
666 * StringUtils.equalsIgnoreCase(null, null) = true
667 * StringUtils.equalsIgnoreCase(null, "abc") = false
668 * StringUtils.equalsIgnoreCase("abc", null) = false
669 * StringUtils.equalsIgnoreCase("abc", "abc") = true
670 * StringUtils.equalsIgnoreCase("abc", "ABC") = true
671 * </pre>
672 *
673 * @see java.lang.String#equalsIgnoreCase(String)
674 * @param str1 the first String, may be null
675 * @param str2 the second String, may be null
676 * @return <code>true</code> if the Strings are equal, case insensitive, or
677 * both <code>null</code>
678 */
679 public static boolean equalsIgnoreCase(String str1, String str2) {
680 return str1 == null ? str2 == null : str1.equalsIgnoreCase(str2);
681 }
682
683 // IndexOf
684 //-----------------------------------------------------------------------
685 /**
686 * <p>Finds the first index within a String, handling <code>null</code>.
687 * This method uses {@link String#indexOf(int)}.</p>
688 *
689 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.< /p>
690 *
691 * <pre>
692 * StringUtils.indexOf(null, *) = -1
693 * StringUtils.indexOf("", *) = -1
694 * StringUtils.indexOf("aabaabaa", 'a') = 0
695 * StringUtils.indexOf("aabaabaa", 'b') = 2
696 * </pre>
697 *
698 * @param str the String to check, may be null
699 * @param searchChar the character to find
700 * @return the first index of the search character,
701 * -1 if no match or <code>null</code> string input
702 * @since 2.0
703 */
704 public static int indexOf(String str, char searchChar) {
705 if (isEmpty(str)) {
706 return -1;
707 }
708 return str.indexOf(searchChar);
709 }
710
711 /**
712 * <p>Finds the first index within a String from a start position,
713 * handling <code>null</code>.
714 * This method uses {@link String#indexOf(int, int)}.</p>
715 *
716 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.
717 * A negative start position is treated as zero.
718 * A start position greater than the string length returns <code>-1</code>.< /p>
719 *
720 * <pre>
721 * StringUtils.indexOf(null, *, *) = -1
722 * StringUtils.indexOf("", *, *) = -1
723 * StringUtils.indexOf("aabaabaa", 'b', 0) = 2
724 * StringUtils.indexOf("aabaabaa", 'b', 3) = 5
725 * StringUtils.indexOf("aabaabaa", 'b', 9) = -1
726 * StringUtils.indexOf("aabaabaa", 'b', -1) = 2
727 * </pre>
728 *
729 * @param str the String to check, may be null
730 * @param searchChar the character to find
731 * @param startPos the start position, negative treated as zero
732 * @return the first index of the search character,
733 * -1 if no match or <code>null</code> string input
734 * @since 2.0
735 */
736 public static int indexOf(String str, char searchChar, int startPos) {
737 if (isEmpty(str)) {
738 return -1;
739 }
740 return str.indexOf(searchChar, startPos);
741 }
742
743 /**
744 * <p>Finds the first index within a String, handling <code>null</code>.
745 * This method uses {@link String#indexOf(String)}.</p>
746 *
747 * <p>A <code>null</code> String will return <code>-1</code>.</p>
748 *
749 * <pre>
750 * StringUtils.indexOf(null, *) = -1
751 * StringUtils.indexOf(*, null) = -1
752 * StringUtils.indexOf("", "") = 0
753 * StringUtils.indexOf("aabaabaa", "a") = 0
754 * StringUtils.indexOf("aabaabaa", "b") = 2
755 * StringUtils.indexOf("aabaabaa", "ab") = 1
756 * StringUtils.indexOf("aabaabaa", "") = 0
757 * </pre>
758 *
759 * @param str the String to check, may be null
760 * @param searchStr the String to find, may be null
761 * @return the first index of the search String,
762 * -1 if no match or <code>null</code> string input
763 * @since 2.0
764 */
765 public static int indexOf(String str, String searchStr) {
766 if (str == null || searchStr == null) {
767 return -1;
768 }
769 return str.indexOf(searchStr);
770 }
771
772 /**
773 * <p>Finds the n-th index within a String, handling <code>null</code>.
774 * This method uses {@link String#indexOf(String)}.</p>
775 *
776 * <p>A <code>null</code> String will return <code>-1</code>.</p>
777 *
778 * <pre>
779 * StringUtils.ordinalIndexOf(null, *, *) = -1
780 * StringUtils.ordinalIndexOf(*, null, *) = -1
781 * StringUtils.ordinalIndexOf("", "", *) = 0
782 * StringUtils.ordinalIndexOf("aabaabaa", "a", 1) = 0
783 * StringUtils.ordinalIndexOf("aabaabaa", "a", 2) = 1
784 * StringUtils.ordinalIndexOf("aabaabaa", "b", 1) = 2
785 * StringUtils.ordinalIndexOf("aabaabaa", "b", 2) = 5
786 * StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1
787 * StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4
788 * StringUtils.ordinalIndexOf("aabaabaa", "", 1) = 0
789 * StringUtils.ordinalIndexOf("aabaabaa", "", 2) = 0
790 * </pre>
791 *
792 * @param str the String to check, may be null
793 * @param searchStr the String to find, may be null
794 * @param ordinal the n-th <code>searchStr</code> to find
795 * @return the n-th index of the search String,
796 * <code>-1</code> (<code>INDEX_NOT_FOUND</code>) if no match or <code>null </code> string input
797 * @since 2.1
798 */
799 public static int ordinalIndexOf(String str, String searchStr, int ordinal) {
800 if (str == null || searchStr == null || ordinal <= 0) {
801 return INDEX_NOT_FOUND;
802 }
803 if (searchStr.length() == 0) {
804 return 0;
805 }
806 int found = 0;
807 int index = INDEX_NOT_FOUND;
808 do {
809 index = str.indexOf(searchStr, index + 1);
810 if (index < 0) {
811 return index;
812 }
813 found++;
814 } while (found < ordinal);
815 return index;
816 }
817
818 /**
819 * <p>Finds the first index within a String, handling <code>null</code>.
820 * This method uses {@link String#indexOf(String, int)}.</p>
821 *
822 * <p>A <code>null</code> String will return <code>-1</code>.
823 * A negative start position is treated as zero.
824 * An empty ("") search String always matches.
825 * A start position greater than the string length only matches
826 * an empty search String.</p>
827 *
828 * <pre>
829 * StringUtils.indexOf(null, *, *) = -1
830 * StringUtils.indexOf(*, null, *) = -1
831 * StringUtils.indexOf("", "", 0) = 0
832 * StringUtils.indexOf("aabaabaa", "a", 0) = 0
833 * StringUtils.indexOf("aabaabaa", "b", 0) = 2
834 * StringUtils.indexOf("aabaabaa", "ab", 0) = 1
835 * StringUtils.indexOf("aabaabaa", "b", 3) = 5
836 * StringUtils.indexOf("aabaabaa", "b", 9) = -1
837 * StringUtils.indexOf("aabaabaa", "b", -1) = 2
838 * StringUtils.indexOf("aabaabaa", "", 2) = 2
839 * StringUtils.indexOf("abc", "", 9) = 3
840 * </pre>
841 *
842 * @param str the String to check, may be null
843 * @param searchStr the String to find, may be null
844 * @param startPos the start position, negative treated as zero
845 * @return the first index of the search String,
846 * -1 if no match or <code>null</code> string input
847 * @since 2.0
848 */
849 public static int indexOf(String str, String searchStr, int startPos) {
850 if (str == null || searchStr == null) {
851 return -1;
852 }
853 // JDK1.2/JDK1.3 have a bug, when startPos > str.length for "", hence
854 if (searchStr.length() == 0 && startPos >= str.length()) {
855 return str.length();
856 }
857 return str.indexOf(searchStr, startPos);
858 }
859
860 // LastIndexOf
861 //-----------------------------------------------------------------------
862 /**
863 * <p>Finds the last index within a String, handling <code>null</code>.
864 * This method uses {@link String#lastIndexOf(int)}.</p>
865 *
866 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.< /p>
867 *
868 * <pre>
869 * StringUtils.lastIndexOf(null, *) = -1
870 * StringUtils.lastIndexOf("", *) = -1
871 * StringUtils.lastIndexOf("aabaabaa", 'a') = 7
872 * StringUtils.lastIndexOf("aabaabaa", 'b') = 5
873 * </pre>
874 *
875 * @param str the String to check, may be null
876 * @param searchChar the character to find
877 * @return the last index of the search character,
878 * -1 if no match or <code>null</code> string input
879 * @since 2.0
880 */
881 public static int lastIndexOf(String str, char searchChar) {
882 if (isEmpty(str)) {
883 return -1;
884 }
885 return str.lastIndexOf(searchChar);
886 }
887
888 /**
889 * <p>Finds the last index within a String from a start position,
890 * handling <code>null</code>.
891 * This method uses {@link String#lastIndexOf(int, int)}.</p>
892 *
893 * <p>A <code>null</code> or empty ("") String will return <code>-1</code>.
894 * A negative start position returns <code>-1</code>.
895 * A start position greater than the string length searches the whole string .</p>
896 *
897 * <pre>
898 * StringUtils.lastIndexOf(null, *, *) = -1
899 * StringUtils.lastIndexOf("", *, *) = -1
900 * StringUtils.lastIndexOf("aabaabaa", 'b', 8) = 5
901 * StringUtils.lastIndexOf("aabaabaa", 'b', 4) = 2
902 * StringUtils.lastIndexOf("aabaabaa", 'b', 0) = -1
903 * StringUtils.lastIndexOf("aabaabaa", 'b', 9) = 5
904 * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1
905 * StringUtils.lastIndexOf("aabaabaa", 'a', 0) = 0
906 * </pre>
907 *
908 * @param str the String to check, may be null
909 * @param searchChar the character to find
910 * @param startPos the start position
911 * @return the last index of the search character,
912 * -1 if no match or <code>null</code> string input
913 * @since 2.0
914 */
915 public static int lastIndexOf(String str, char searchChar, int startPos) {
916 if (isEmpty(str)) {
917 return -1;
918 }
919 return str.lastIndexOf(searchChar, startPos);
920 }
921
922 /**
923 * <p>Finds the last index within a String, handling <code>null</code>.
924 * This method uses {@link String#lastIndexOf(String)}.</p>
925 *
926 * <p>A <code>null</code> String will return <code>-1</code>.</p>
927 *
928 * <pre>
929 * StringUtils.lastIndexOf(null, *) = -1
930 * StringUtils.lastIndexOf(*, null) = -1
931 * StringUtils.lastIndexOf("", "") = 0
932 * StringUtils.lastIndexOf("aabaabaa", "a") = 0
933 * StringUtils.lastIndexOf("aabaabaa", "b") = 2
934 * StringUtils.lastIndexOf("aabaabaa", "ab") = 1
935 * StringUtils.lastIndexOf("aabaabaa", "") = 8
936 * </pre>
937 *
938 * @param str the String to check, may be null
939 * @param searchStr the String to find, may be null
940 * @return the last index of the search String,
941 * -1 if no match or <code>null</code> string input
942 * @since 2.0
943 */
944 public static int lastIndexOf(String str, String searchStr) {
945 if (str == null || searchStr == null) {
946 return -1;
947 }
948 return str.lastIndexOf(searchStr);
949 }
950
951 /**
952 * <p>Finds the first index within a String, handling <code>null</code>.
953 * This method uses {@link String#lastIndexOf(String, int)}.</p>
954 *
955 * <p>A <code>null</code> String will return <code>-1</code>.
956 * A negative start position returns <code>-1</code>.
957 * An empty ("") search String always matches unless the start position is n egative.
958 * A start position greater than the string length searches the whole string .</p>
959 *
960 * <pre>
961 * StringUtils.lastIndexOf(null, *, *) = -1
962 * StringUtils.lastIndexOf(*, null, *) = -1
963 * StringUtils.lastIndexOf("aabaabaa", "a", 8) = 7
964 * StringUtils.lastIndexOf("aabaabaa", "b", 8) = 5
965 * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4
966 * StringUtils.lastIndexOf("aabaabaa", "b", 9) = 5
967 * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1
968 * StringUtils.lastIndexOf("aabaabaa", "a", 0) = 0
969 * StringUtils.lastIndexOf("aabaabaa", "b", 0) = -1
970 * </pre>
971 *
972 * @param str the String to check, may be null
973 * @param searchStr the String to find, may be null
974 * @param startPos the start position, negative treated as zero
975 * @return the first index of the search String,
976 * -1 if no match or <code>null</code> string input
977 * @since 2.0
978 */
979 public static int lastIndexOf(String str, String searchStr, int startPos) {
980 if (str == null || searchStr == null) {
981 return -1;
982 }
983 return str.lastIndexOf(searchStr, startPos);
984 }
985
986 // Contains
987 //-----------------------------------------------------------------------
988 /**
989 * <p>Checks if String contains a search character, handling <code>null</cod e>.
990 * This method uses {@link String#indexOf(int)}.</p>
991 *
992 * <p>A <code>null</code> or empty ("") String will return <code>false</code >.</p>
993 *
994 * <pre>
995 * StringUtils.contains(null, *) = false
996 * StringUtils.contains("", *) = false
997 * StringUtils.contains("abc", 'a') = true
998 * StringUtils.contains("abc", 'z') = false
999 * </pre>
1000 *
1001 * @param str the String to check, may be null
1002 * @param searchChar the character to find
1003 * @return true if the String contains the search character,
1004 * false if not or <code>null</code> string input
1005 * @since 2.0
1006 */
1007 public static boolean contains(String str, char searchChar) {
1008 if (isEmpty(str)) {
1009 return false;
1010 }
1011 return str.indexOf(searchChar) >= 0;
1012 }
1013
1014 /**
1015 * <p>Checks if String contains a search String, handling <code>null</code>.
1016 * This method uses {@link String#indexOf(String)}.</p>
1017 *
1018 * <p>A <code>null</code> String will return <code>false</code>.</p>
1019 *
1020 * <pre>
1021 * StringUtils.contains(null, *) = false
1022 * StringUtils.contains(*, null) = false
1023 * StringUtils.contains("", "") = true
1024 * StringUtils.contains("abc", "") = true
1025 * StringUtils.contains("abc", "a") = true
1026 * StringUtils.contains("abc", "z") = false
1027 * </pre>
1028 *
1029 * @param str the String to check, may be null
1030 * @param searchStr the String to find, may be null
1031 * @return true if the String contains the search String,
1032 * false if not or <code>null</code> string input
1033 * @since 2.0
1034 */
1035 public static boolean contains(String str, String searchStr) {
1036 if (str == null || searchStr == null) {
1037 return false;
1038 }
1039 return str.indexOf(searchStr) >= 0;
1040 }
1041
1042 /**
1043 * <p>Checks if String contains a search String irrespective of case,
1044 * handling <code>null</code>. This method uses
1045 * {@link #contains(String, String)}.</p>
1046 *
1047 * <p>A <code>null</code> String will return <code>false</code>.</p>
1048 *
1049 * <pre>
1050 * StringUtils.contains(null, *) = false
1051 * StringUtils.contains(*, null) = false
1052 * StringUtils.contains("", "") = true
1053 * StringUtils.contains("abc", "") = true
1054 * StringUtils.contains("abc", "a") = true
1055 * StringUtils.contains("abc", "z") = false
1056 * StringUtils.contains("abc", "A") = true
1057 * StringUtils.contains("abc", "Z") = false
1058 * </pre>
1059 *
1060 * @param str the String to check, may be null
1061 * @param searchStr the String to find, may be null
1062 * @return true if the String contains the search String irrespective of
1063 * case or false if not or <code>null</code> string input
1064 */
1065 public static boolean containsIgnoreCase(String str, String searchStr) {
1066 if (str == null || searchStr == null) {
1067 return false;
1068 }
1069 return contains(str.toUpperCase(), searchStr.toUpperCase());
1070 }
1071
1072 // ContainsAny
1073 //-----------------------------------------------------------------------
1074 /**
1075 * <p>Checks if the String contains any character in the given
1076 * set of characters.</p>
1077 *
1078 * <p>A <code>null</code> String will return <code>false</code>.
1079 * A <code>null</code> or zero length search array will return <code>false</ code>.</p>
1080 *
1081 * <pre>
1082 * StringUtils.containsAny(null, *) = false
1083 * StringUtils.containsAny("", *) = false
1084 * StringUtils.containsAny(*, null) = false
1085 * StringUtils.containsAny(*, []) = false
1086 * StringUtils.containsAny("zzabyycdxx",['z','a']) = true
1087 * StringUtils.containsAny("zzabyycdxx",['b','y']) = true
1088 * StringUtils.containsAny("aba", ['z']) = false
1089 * </pre>
1090 *
1091 * @param str the String to check, may be null
1092 * @param searchChars the chars to search for, may be null
1093 * @return the <code>true</code> if any of the chars are found,
1094 * <code>false</code> if no match or null input
1095 * @since 2.4
1096 */
1097 public static boolean containsAny(String str, char[] searchChars) {
1098 if (str == null || str.length() == 0 || searchChars == null || searchCha rs.length == 0) {
1099 return false;
1100 }
1101 for (int i = 0; i < str.length(); i++) {
1102 char ch = str.charAt(i);
1103 for (int j = 0; j < searchChars.length; j++) {
1104 if (searchChars[j] == ch) {
1105 return true;
1106 }
1107 }
1108 }
1109 return false;
1110 }
1111
1112 /**
1113 * <p>
1114 * Checks if the String contains any character in the given set of character s.
1115 * </p>
1116 *
1117 * <p>
1118 * A <code>null</code> String will return <code>false</code>. A <code>null</ code> search string will return
1119 * <code>false</code>.
1120 * </p>
1121 *
1122 * <pre>
1123 * StringUtils.containsAny(null, *) = false
1124 * StringUtils.containsAny("", *) = false
1125 * StringUtils.containsAny(*, null) = false
1126 * StringUtils.containsAny(*, "") = false
1127 * StringUtils.containsAny("zzabyycdxx", "za") = true
1128 * StringUtils.containsAny("zzabyycdxx", "by") = true
1129 * StringUtils.containsAny("aba","z") = false
1130 * </pre>
1131 *
1132 * @param str
1133 * the String to check, may be null
1134 * @param searchChars
1135 * the chars to search for, may be null
1136 * @return the <code>true</code> if any of the chars are found, <code>false< /code> if no match or null input
1137 * @since 2.4
1138 */
1139 public static boolean containsAny(String str, String searchChars) {
1140 if (searchChars == null) {
1141 return false;
1142 }
1143 return containsAny(str, searchChars.toCharArray());
1144 }
1145
1146 /**
1147 * <p>Search a String to find the first index of any
1148 * character not in the given set of characters.</p>
1149 *
1150 * <p>A <code>null</code> String will return <code>-1</code>.
1151 * A <code>null</code> search string will return <code>-1</code>.</p>
1152 *
1153 * <pre>
1154 * StringUtils.indexOfAnyBut(null, *) = -1
1155 * StringUtils.indexOfAnyBut("", *) = -1
1156 * StringUtils.indexOfAnyBut(*, null) = -1
1157 * StringUtils.indexOfAnyBut(*, "") = -1
1158 * StringUtils.indexOfAnyBut("zzabyycdxx", "za") = 3
1159 * StringUtils.indexOfAnyBut("zzabyycdxx", "") = 0
1160 * StringUtils.indexOfAnyBut("aba","ab") = -1
1161 * </pre>
1162 *
1163 * @param str the String to check, may be null
1164 * @param searchChars the chars to search for, may be null
1165 * @return the index of any of the chars, -1 if no match or null input
1166 * @since 2.0
1167 */
1168 public static int indexOfAnyBut(String str, String searchChars) {
1169 if (isEmpty(str) || isEmpty(searchChars)) {
1170 return -1;
1171 }
1172 for (int i = 0; i < str.length(); i++) {
1173 if (searchChars.indexOf(str.charAt(i)) < 0) {
1174 return i;
1175 }
1176 }
1177 return -1;
1178 }
1179
1180 // ContainsNone
1181 //-----------------------------------------------------------------------
1182 /**
1183 * <p>Checks that the String does not contain certain characters.</p>
1184 *
1185 * <p>A <code>null</code> String will return <code>true</code>.
1186 * A <code>null</code> invalid character array will return <code>true</code> .
1187 * An empty String ("") always returns true.</p>
1188 *
1189 * <pre>
1190 * StringUtils.containsNone(null, *) = true
1191 * StringUtils.containsNone(*, null) = true
1192 * StringUtils.containsNone("", *) = true
1193 * StringUtils.containsNone("ab", '') = true
1194 * StringUtils.containsNone("abab", 'xyz') = true
1195 * StringUtils.containsNone("ab1", 'xyz') = true
1196 * StringUtils.containsNone("abz", 'xyz') = false
1197 * </pre>
1198 *
1199 * @param str the String to check, may be null
1200 * @param invalidChars an array of invalid chars, may be null
1201 * @return true if it contains none of the invalid chars, or is null
1202 * @since 2.0
1203 */
1204 public static boolean containsNone(String str, char[] invalidChars) {
1205 if (str == null || invalidChars == null) {
1206 return true;
1207 }
1208 int strSize = str.length();
1209 int validSize = invalidChars.length;
1210 for (int i = 0; i < strSize; i++) {
1211 char ch = str.charAt(i);
1212 for (int j = 0; j < validSize; j++) {
1213 if (invalidChars[j] == ch) {
1214 return false;
1215 }
1216 }
1217 }
1218 return true;
1219 }
1220
1221 /**
1222 * <p>Checks that the String does not contain certain characters.</p>
1223 *
1224 * <p>A <code>null</code> String will return <code>true</code>.
1225 * A <code>null</code> invalid character array will return <code>true</code> .
1226 * An empty String ("") always returns true.</p>
1227 *
1228 * <pre>
1229 * StringUtils.containsNone(null, *) = true
1230 * StringUtils.containsNone(*, null) = true
1231 * StringUtils.containsNone("", *) = true
1232 * StringUtils.containsNone("ab", "") = true
1233 * StringUtils.containsNone("abab", "xyz") = true
1234 * StringUtils.containsNone("ab1", "xyz") = true
1235 * StringUtils.containsNone("abz", "xyz") = false
1236 * </pre>
1237 *
1238 * @param str the String to check, may be null
1239 * @param invalidChars a String of invalid chars, may be null
1240 * @return true if it contains none of the invalid chars, or is null
1241 * @since 2.0
1242 */
1243 public static boolean containsNone(String str, String invalidChars) {
1244 if (str == null || invalidChars == null) {
1245 return true;
1246 }
1247 return containsNone(str, invalidChars.toCharArray());
1248 }
1249
1250 // IndexOfAny strings
1251 //-----------------------------------------------------------------------
1252 /**
1253 * <p>Find the first index of any of a set of potential substrings.</p>
1254 *
1255 * <p>A <code>null</code> String will return <code>-1</code>.
1256 * A <code>null</code> or zero length search array will return <code>-1</cod e>.
1257 * A <code>null</code> search array entry will be ignored, but a search
1258 * array containing "" will return <code>0</code> if <code>str</code> is not
1259 * null. This method uses {@link String#indexOf(String)}.</p>
1260 *
1261 * <pre>
1262 * StringUtils.indexOfAny(null, *) = -1
1263 * StringUtils.indexOfAny(*, null) = -1
1264 * StringUtils.indexOfAny(*, []) = -1
1265 * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"]) = 2
1266 * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"]) = 2
1267 * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"]) = -1
1268 * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
1269 * StringUtils.indexOfAny("zzabyycdxx", [""]) = 0
1270 * StringUtils.indexOfAny("", [""]) = 0
1271 * StringUtils.indexOfAny("", ["a"]) = -1
1272 * </pre>
1273 *
1274 * @param str the String to check, may be null
1275 * @param searchStrs the Strings to search for, may be null
1276 * @return the first index of any of the searchStrs in str, -1 if no match
1277 */
1278 public static int indexOfAny(String str, String[] searchStrs) {
1279 if ((str == null) || (searchStrs == null)) {
1280 return -1;
1281 }
1282 int sz = searchStrs.length;
1283
1284 // String's can't have a MAX_VALUEth index.
1285 int ret = Integer.MAX_VALUE;
1286
1287 int tmp = 0;
1288 for (int i = 0; i < sz; i++) {
1289 String search = searchStrs[i];
1290 if (search == null) {
1291 continue;
1292 }
1293 tmp = str.indexOf(search);
1294 if (tmp == -1) {
1295 continue;
1296 }
1297
1298 if (tmp < ret) {
1299 ret = tmp;
1300 }
1301 }
1302
1303 return (ret == Integer.MAX_VALUE) ? -1 : ret;
1304 }
1305
1306 /**
1307 * <p>Find the latest index of any of a set of potential substrings.</p>
1308 *
1309 * <p>A <code>null</code> String will return <code>-1</code>.
1310 * A <code>null</code> search array will return <code>-1</code>.
1311 * A <code>null</code> or zero length search array entry will be ignored,
1312 * but a search array containing "" will return the length of <code>str</cod e>
1313 * if <code>str</code> is not null. This method uses {@link String#indexOf(S tring)}</p>
1314 *
1315 * <pre>
1316 * StringUtils.lastIndexOfAny(null, *) = -1
1317 * StringUtils.lastIndexOfAny(*, null) = -1
1318 * StringUtils.lastIndexOfAny(*, []) = -1
1319 * StringUtils.lastIndexOfAny(*, [null]) = -1
1320 * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
1321 * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
1322 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
1323 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
1324 * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""]) = 10
1325 * </pre>
1326 *
1327 * @param str the String to check, may be null
1328 * @param searchStrs the Strings to search for, may be null
1329 * @return the last index of any of the Strings, -1 if no match
1330 */
1331 public static int lastIndexOfAny(String str, String[] searchStrs) {
1332 if ((str == null) || (searchStrs == null)) {
1333 return -1;
1334 }
1335 int sz = searchStrs.length;
1336 int ret = -1;
1337 int tmp = 0;
1338 for (int i = 0; i < sz; i++) {
1339 String search = searchStrs[i];
1340 if (search == null) {
1341 continue;
1342 }
1343 tmp = str.lastIndexOf(search);
1344 if (tmp > ret) {
1345 ret = tmp;
1346 }
1347 }
1348 return ret;
1349 }
1350
1351 // Substring
1352 //-----------------------------------------------------------------------
1353 /**
1354 * <p>Gets a substring from the specified String avoiding exceptions.</p>
1355 *
1356 * <p>A negative start position can be used to start <code>n</code>
1357 * characters from the end of the String.</p>
1358 *
1359 * <p>A <code>null</code> String will return <code>null</code>.
1360 * An empty ("") String will return "".</p>
1361 *
1362 * <pre>
1363 * StringUtils.substring(null, *) = null
1364 * StringUtils.substring("", *) = ""
1365 * StringUtils.substring("abc", 0) = "abc"
1366 * StringUtils.substring("abc", 2) = "c"
1367 * StringUtils.substring("abc", 4) = ""
1368 * StringUtils.substring("abc", -2) = "bc"
1369 * StringUtils.substring("abc", -4) = "abc"
1370 * </pre>
1371 *
1372 * @param str the String to get the substring from, may be null
1373 * @param start the position to start from, negative means
1374 * count back from the end of the String by this many characters
1375 * @return substring from start position, <code>null</code> if null String i nput
1376 */
1377 public static String substring(String str, int start) {
1378 if (str == null) {
1379 return null;
1380 }
1381
1382 // handle negatives, which means last n characters
1383 if (start < 0) {
1384 start = str.length() + start; // remember start is negative
1385 }
1386
1387 if (start < 0) {
1388 start = 0;
1389 }
1390 if (start > str.length()) {
1391 return EMPTY;
1392 }
1393
1394 return str.substring(start);
1395 }
1396
1397 /**
1398 * <p>Gets a substring from the specified String avoiding exceptions.</p>
1399 *
1400 * <p>A negative start position can be used to start/end <code>n</code>
1401 * characters from the end of the String.</p>
1402 *
1403 * <p>The returned substring starts with the character in the <code>start</c ode>
1404 * position and ends before the <code>end</code> position. All position coun ting is
1405 * zero-based -- i.e., to start at the beginning of the string use
1406 * <code>start = 0</code>. Negative start and end positions can be used to
1407 * specify offsets relative to the end of the String.</p>
1408 *
1409 * <p>If <code>start</code> is not strictly to the left of <code>end</code>, ""
1410 * is returned.</p>
1411 *
1412 * <pre>
1413 * StringUtils.substring(null, *, *) = null
1414 * StringUtils.substring("", * , *) = "";
1415 * StringUtils.substring("abc", 0, 2) = "ab"
1416 * StringUtils.substring("abc", 2, 0) = ""
1417 * StringUtils.substring("abc", 2, 4) = "c"
1418 * StringUtils.substring("abc", 4, 6) = ""
1419 * StringUtils.substring("abc", 2, 2) = ""
1420 * StringUtils.substring("abc", -2, -1) = "b"
1421 * StringUtils.substring("abc", -4, 2) = "ab"
1422 * </pre>
1423 *
1424 * @param str the String to get the substring from, may be null
1425 * @param start the position to start from, negative means
1426 * count back from the end of the String by this many characters
1427 * @param end the position to end at (exclusive), negative means
1428 * count back from the end of the String by this many characters
1429 * @return substring from start position to end positon,
1430 * <code>null</code> if null String input
1431 */
1432 public static String substring(String str, int start, int end) {
1433 if (str == null) {
1434 return null;
1435 }
1436
1437 // handle negatives
1438 if (end < 0) {
1439 end = str.length() + end; // remember end is negative
1440 }
1441 if (start < 0) {
1442 start = str.length() + start; // remember start is negative
1443 }
1444
1445 // check length next
1446 if (end > str.length()) {
1447 end = str.length();
1448 }
1449
1450 // if start is greater than end, return ""
1451 if (start > end) {
1452 return EMPTY;
1453 }
1454
1455 if (start < 0) {
1456 start = 0;
1457 }
1458 if (end < 0) {
1459 end = 0;
1460 }
1461
1462 return str.substring(start, end);
1463 }
1464
1465 // Left/Right/Mid
1466 //-----------------------------------------------------------------------
1467 /**
1468 * <p>Gets the leftmost <code>len</code> characters of a String.</p>
1469 *
1470 * <p>If <code>len</code> characters are not available, or the
1471 * String is <code>null</code>, the String will be returned without
1472 * an exception. An exception is thrown if len is negative.</p>
1473 *
1474 * <pre>
1475 * StringUtils.left(null, *) = null
1476 * StringUtils.left(*, -ve) = ""
1477 * StringUtils.left("", *) = ""
1478 * StringUtils.left("abc", 0) = ""
1479 * StringUtils.left("abc", 2) = "ab"
1480 * StringUtils.left("abc", 4) = "abc"
1481 * </pre>
1482 *
1483 * @param str the String to get the leftmost characters from, may be null
1484 * @param len the length of the required String, must be zero or positive
1485 * @return the leftmost characters, <code>null</code> if null String input
1486 */
1487 public static String left(String str, int len) {
1488 if (str == null) {
1489 return null;
1490 }
1491 if (len < 0) {
1492 return EMPTY;
1493 }
1494 if (str.length() <= len) {
1495 return str;
1496 }
1497 return str.substring(0, len);
1498 }
1499
1500 /**
1501 * <p>Gets the rightmost <code>len</code> characters of a String.</p>
1502 *
1503 * <p>If <code>len</code> characters are not available, or the String
1504 * is <code>null</code>, the String will be returned without an
1505 * an exception. An exception is thrown if len is negative.</p>
1506 *
1507 * <pre>
1508 * StringUtils.right(null, *) = null
1509 * StringUtils.right(*, -ve) = ""
1510 * StringUtils.right("", *) = ""
1511 * StringUtils.right("abc", 0) = ""
1512 * StringUtils.right("abc", 2) = "bc"
1513 * StringUtils.right("abc", 4) = "abc"
1514 * </pre>
1515 *
1516 * @param str the String to get the rightmost characters from, may be null
1517 * @param len the length of the required String, must be zero or positive
1518 * @return the rightmost characters, <code>null</code> if null String input
1519 */
1520 public static String right(String str, int len) {
1521 if (str == null) {
1522 return null;
1523 }
1524 if (len < 0) {
1525 return EMPTY;
1526 }
1527 if (str.length() <= len) {
1528 return str;
1529 }
1530 return str.substring(str.length() - len);
1531 }
1532
1533 /**
1534 * <p>Gets <code>len</code> characters from the middle of a String.</p>
1535 *
1536 * <p>If <code>len</code> characters are not available, the remainder
1537 * of the String will be returned without an exception. If the
1538 * String is <code>null</code>, <code>null</code> will be returned.
1539 * An exception is thrown if len is negative.</p>
1540 *
1541 * <pre>
1542 * StringUtils.mid(null, *, *) = null
1543 * StringUtils.mid(*, *, -ve) = ""
1544 * StringUtils.mid("", 0, *) = ""
1545 * StringUtils.mid("abc", 0, 2) = "ab"
1546 * StringUtils.mid("abc", 0, 4) = "abc"
1547 * StringUtils.mid("abc", 2, 4) = "c"
1548 * StringUtils.mid("abc", 4, 2) = ""
1549 * StringUtils.mid("abc", -2, 2) = "ab"
1550 * </pre>
1551 *
1552 * @param str the String to get the characters from, may be null
1553 * @param pos the position to start from, negative treated as zero
1554 * @param len the length of the required String, must be zero or positive
1555 * @return the middle characters, <code>null</code> if null String input
1556 */
1557 public static String mid(String str, int pos, int len) {
1558 if (str == null) {
1559 return null;
1560 }
1561 if (len < 0 || pos > str.length()) {
1562 return EMPTY;
1563 }
1564 if (pos < 0) {
1565 pos = 0;
1566 }
1567 if (str.length() <= (pos + len)) {
1568 return str.substring(pos);
1569 }
1570 return str.substring(pos, pos + len);
1571 }
1572
1573 // SubStringAfter/SubStringBefore
1574 //-----------------------------------------------------------------------
1575 /**
1576 * <p>Gets the substring before the first occurrence of a separator.
1577 * The separator is not returned.</p>
1578 *
1579 * <p>A <code>null</code> string input will return <code>null</code>.
1580 * An empty ("") string input will return the empty string.
1581 * A <code>null</code> separator will return the input string.</p>
1582 *
1583 * <pre>
1584 * StringUtils.substringBefore(null, *) = null
1585 * StringUtils.substringBefore("", *) = ""
1586 * StringUtils.substringBefore("abc", "a") = ""
1587 * StringUtils.substringBefore("abcba", "b") = "a"
1588 * StringUtils.substringBefore("abc", "c") = "ab"
1589 * StringUtils.substringBefore("abc", "d") = "abc"
1590 * StringUtils.substringBefore("abc", "") = ""
1591 * StringUtils.substringBefore("abc", null) = "abc"
1592 * </pre>
1593 *
1594 * @param str the String to get a substring from, may be null
1595 * @param separator the String to search for, may be null
1596 * @return the substring before the first occurrence of the separator,
1597 * <code>null</code> if null String input
1598 * @since 2.0
1599 */
1600 public static String substringBefore(String str, String separator) {
1601 if (isEmpty(str) || separator == null) {
1602 return str;
1603 }
1604 if (separator.length() == 0) {
1605 return EMPTY;
1606 }
1607 int pos = str.indexOf(separator);
1608 if (pos == -1) {
1609 return str;
1610 }
1611 return str.substring(0, pos);
1612 }
1613
1614 /**
1615 * <p>Gets the substring after the first occurrence of a separator.
1616 * The separator is not returned.</p>
1617 *
1618 * <p>A <code>null</code> string input will return <code>null</code>.
1619 * An empty ("") string input will return the empty string.
1620 * A <code>null</code> separator will return the empty string if the
1621 * input string is not <code>null</code>.</p>
1622 *
1623 * <pre>
1624 * StringUtils.substringAfter(null, *) = null
1625 * StringUtils.substringAfter("", *) = ""
1626 * StringUtils.substringAfter(*, null) = ""
1627 * StringUtils.substringAfter("abc", "a") = "bc"
1628 * StringUtils.substringAfter("abcba", "b") = "cba"
1629 * StringUtils.substringAfter("abc", "c") = ""
1630 * StringUtils.substringAfter("abc", "d") = ""
1631 * StringUtils.substringAfter("abc", "") = "abc"
1632 * </pre>
1633 *
1634 * @param str the String to get a substring from, may be null
1635 * @param separator the String to search for, may be null
1636 * @return the substring after the first occurrence of the separator,
1637 * <code>null</code> if null String input
1638 * @since 2.0
1639 */
1640 public static String substringAfter(String str, String separator) {
1641 if (isEmpty(str)) {
1642 return str;
1643 }
1644 if (separator == null) {
1645 return EMPTY;
1646 }
1647 int pos = str.indexOf(separator);
1648 if (pos == -1) {
1649 return EMPTY;
1650 }
1651 return str.substring(pos + separator.length());
1652 }
1653
1654 /**
1655 * <p>Gets the substring before the last occurrence of a separator.
1656 * The separator is not returned.</p>
1657 *
1658 * <p>A <code>null</code> string input will return <code>null</code>.
1659 * An empty ("") string input will return the empty string.
1660 * An empty or <code>null</code> separator will return the input string.</p>
1661 *
1662 * <pre>
1663 * StringUtils.substringBeforeLast(null, *) = null
1664 * StringUtils.substringBeforeLast("", *) = ""
1665 * StringUtils.substringBeforeLast("abcba", "b") = "abc"
1666 * StringUtils.substringBeforeLast("abc", "c") = "ab"
1667 * StringUtils.substringBeforeLast("a", "a") = ""
1668 * StringUtils.substringBeforeLast("a", "z") = "a"
1669 * StringUtils.substringBeforeLast("a", null) = "a"
1670 * StringUtils.substringBeforeLast("a", "") = "a"
1671 * </pre>
1672 *
1673 * @param str the String to get a substring from, may be null
1674 * @param separator the String to search for, may be null
1675 * @return the substring before the last occurrence of the separator,
1676 * <code>null</code> if null String input
1677 * @since 2.0
1678 */
1679 public static String substringBeforeLast(String str, String separator) {
1680 if (isEmpty(str) || isEmpty(separator)) {
1681 return str;
1682 }
1683 int pos = str.lastIndexOf(separator);
1684 if (pos == -1) {
1685 return str;
1686 }
1687 return str.substring(0, pos);
1688 }
1689
1690 /**
1691 * <p>Gets the substring after the last occurrence of a separator.
1692 * The separator is not returned.</p>
1693 *
1694 * <p>A <code>null</code> string input will return <code>null</code>.
1695 * An empty ("") string input will return the empty string.
1696 * An empty or <code>null</code> separator will return the empty string if
1697 * the input string is not <code>null</code>.</p>
1698 *
1699 * <pre>
1700 * StringUtils.substringAfterLast(null, *) = null
1701 * StringUtils.substringAfterLast("", *) = ""
1702 * StringUtils.substringAfterLast(*, "") = ""
1703 * StringUtils.substringAfterLast(*, null) = ""
1704 * StringUtils.substringAfterLast("abc", "a") = "bc"
1705 * StringUtils.substringAfterLast("abcba", "b") = "a"
1706 * StringUtils.substringAfterLast("abc", "c") = ""
1707 * StringUtils.substringAfterLast("a", "a") = ""
1708 * StringUtils.substringAfterLast("a", "z") = ""
1709 * </pre>
1710 *
1711 * @param str the String to get a substring from, may be null
1712 * @param separator the String to search for, may be null
1713 * @return the substring after the last occurrence of the separator,
1714 * <code>null</code> if null String input
1715 * @since 2.0
1716 */
1717 public static String substringAfterLast(String str, String separator) {
1718 if (isEmpty(str)) {
1719 return str;
1720 }
1721 if (isEmpty(separator)) {
1722 return EMPTY;
1723 }
1724 int pos = str.lastIndexOf(separator);
1725 if (pos == -1 || pos == (str.length() - separator.length())) {
1726 return EMPTY;
1727 }
1728 return str.substring(pos + separator.length());
1729 }
1730
1731 // Substring between
1732 //-----------------------------------------------------------------------
1733 /**
1734 * <p>Gets the String that is nested in between two instances of the
1735 * same String.</p>
1736 *
1737 * <p>A <code>null</code> input String returns <code>null</code>.
1738 * A <code>null</code> tag returns <code>null</code>.</p>
1739 *
1740 * <pre>
1741 * StringUtils.substringBetween(null, *) = null
1742 * StringUtils.substringBetween("", "") = ""
1743 * StringUtils.substringBetween("", "tag") = null
1744 * StringUtils.substringBetween("tagabctag", null) = null
1745 * StringUtils.substringBetween("tagabctag", "") = ""
1746 * StringUtils.substringBetween("tagabctag", "tag") = "abc"
1747 * </pre>
1748 *
1749 * @param str the String containing the substring, may be null
1750 * @param tag the String before and after the substring, may be null
1751 * @return the substring, <code>null</code> if no match
1752 * @since 2.0
1753 */
1754 public static String substringBetween(String str, String tag) {
1755 return substringBetween(str, tag, tag);
1756 }
1757
1758 /**
1759 * <p>Gets the String that is nested in between two Strings.
1760 * Only the first match is returned.</p>
1761 *
1762 * <p>A <code>null</code> input String returns <code>null</code>.
1763 * A <code>null</code> open/close returns <code>null</code> (no match).
1764 * An empty ("") open and close returns an empty string.</p>
1765 *
1766 * <pre>
1767 * StringUtils.substringBetween("wx[b]yz", "[", "]") = "b"
1768 * StringUtils.substringBetween(null, *, *) = null
1769 * StringUtils.substringBetween(*, null, *) = null
1770 * StringUtils.substringBetween(*, *, null) = null
1771 * StringUtils.substringBetween("", "", "") = ""
1772 * StringUtils.substringBetween("", "", "]") = null
1773 * StringUtils.substringBetween("", "[", "]") = null
1774 * StringUtils.substringBetween("yabcz", "", "") = ""
1775 * StringUtils.substringBetween("yabcz", "y", "z") = "abc"
1776 * StringUtils.substringBetween("yabczyabcz", "y", "z") = "abc"
1777 * </pre>
1778 *
1779 * @param str the String containing the substring, may be null
1780 * @param open the String before the substring, may be null
1781 * @param close the String after the substring, may be null
1782 * @return the substring, <code>null</code> if no match
1783 * @since 2.0
1784 */
1785 public static String substringBetween(String str, String open, String close) {
1786 if (str == null || open == null || close == null) {
1787 return null;
1788 }
1789 int start = str.indexOf(open);
1790 if (start != -1) {
1791 int end = str.indexOf(close, start + open.length());
1792 if (end != -1) {
1793 return str.substring(start + open.length(), end);
1794 }
1795 }
1796 return null;
1797 }
1798
1799 // Joining
1800 //-----------------------------------------------------------------------
1801 /**
1802 * <p>Concatenates elements of an array into a single String.
1803 * Null objects or empty strings within the array are represented by
1804 * empty strings.</p>
1805 *
1806 * <pre>
1807 * StringUtils.concatenate(null) = null
1808 * StringUtils.concatenate([]) = ""
1809 * StringUtils.concatenate([null]) = ""
1810 * StringUtils.concatenate(["a", "b", "c"]) = "abc"
1811 * StringUtils.concatenate([null, "", "a"]) = "a"
1812 * </pre>
1813 *
1814 * @param array the array of values to concatenate, may be null
1815 * @return the concatenated String, <code>null</code> if null array input
1816 * @deprecated Use the better named {@link #join(Object[])} instead.
1817 * Method will be removed in Commons Lang 3.0.
1818 */
1819 public static String concatenate(Object[] array) {
1820 return join(array, null);
1821 }
1822
1823 /**
1824 * <p>Joins the elements of the provided array into a single String
1825 * containing the provided list of elements.</p>
1826 *
1827 * <p>No separator is added to the joined String.
1828 * Null objects or empty strings within the array are represented by
1829 * empty strings.</p>
1830 *
1831 * <pre>
1832 * StringUtils.join(null) = null
1833 * StringUtils.join([]) = ""
1834 * StringUtils.join([null]) = ""
1835 * StringUtils.join(["a", "b", "c"]) = "abc"
1836 * StringUtils.join([null, "", "a"]) = "a"
1837 * </pre>
1838 *
1839 * @param array the array of values to join together, may be null
1840 * @return the joined String, <code>null</code> if null array input
1841 * @since 2.0
1842 */
1843 public static String join(Object[] array) {
1844 return join(array, null);
1845 }
1846
1847 /**
1848 * <p>Joins the elements of the provided array into a single String
1849 * containing the provided list of elements.</p>
1850 *
1851 * <p>No delimiter is added before or after the list.
1852 * Null objects or empty strings within the array are represented by
1853 * empty strings.</p>
1854 *
1855 * <pre>
1856 * StringUtils.join(null, *) = null
1857 * StringUtils.join([], *) = ""
1858 * StringUtils.join([null], *) = ""
1859 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
1860 * StringUtils.join(["a", "b", "c"], null) = "abc"
1861 * StringUtils.join([null, "", "a"], ';') = ";;a"
1862 * </pre>
1863 *
1864 * @param array the array of values to join together, may be null
1865 * @param separator the separator character to use
1866 * @return the joined String, <code>null</code> if null array input
1867 * @since 2.0
1868 */
1869 public static String join(Object[] array, char separator) {
1870 if (array == null) {
1871 return null;
1872 }
1873
1874 return join(array, separator, 0, array.length);
1875 }
1876
1877 /**
1878 * <p>Joins the elements of the provided array into a single String
1879 * containing the provided list of elements.</p>
1880 *
1881 * <p>No delimiter is added before or after the list.
1882 * Null objects or empty strings within the array are represented by
1883 * empty strings.</p>
1884 *
1885 * <pre>
1886 * StringUtils.join(null, *) = null
1887 * StringUtils.join([], *) = ""
1888 * StringUtils.join([null], *) = ""
1889 * StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
1890 * StringUtils.join(["a", "b", "c"], null) = "abc"
1891 * StringUtils.join([null, "", "a"], ';') = ";;a"
1892 * </pre>
1893 *
1894 * @param array the array of values to join together, may be null
1895 * @param separator the separator character to use
1896 * @param startIndex the first index to start joining from. It is
1897 * an error to pass in an end index past the end of the array
1898 * @param endIndex the index to stop joining from (exclusive). It is
1899 * an error to pass in an end index past the end of the array
1900 * @return the joined String, <code>null</code> if null array input
1901 * @since 2.0
1902 */
1903 public static String join(Object[] array, char separator, int startIndex, in t endIndex) {
1904 if (array == null) {
1905 return null;
1906 }
1907 int bufSize = (endIndex - startIndex);
1908 if (bufSize <= 0) {
1909 return EMPTY;
1910 }
1911
1912 bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString ().length()) + 1);
1913 StringBuffer buf = new StringBuffer(bufSize);
1914
1915 for (int i = startIndex; i < endIndex; i++) {
1916 if (i > startIndex) {
1917 buf.append(separator);
1918 }
1919 if (array[i] != null) {
1920 buf.append(array[i]);
1921 }
1922 } 3441 }
1923 return buf.toString(); 3442 return buf.toString();
1924 } 3443 }
1925 3444 }
1926 3445
1927 /** 3446 /**
1928 * <p>Joins the elements of the provided array into a single String 3447 * <p>Returns padding using the specified delimiter repeated
1929 * containing the provided list of elements.</p> 3448 * to a given length.</p>
1930 * 3449 * <p/>
1931 * <p>No delimiter is added before or after the list. 3450 * <pre>
1932 * A <code>null</code> separator is the same as an empty String (""). 3451 * StringUtils.padding(0, 'e') = ""
1933 * Null objects or empty strings within the array are represented by 3452 * StringUtils.padding(3, 'e') = "eee"
1934 * empty strings.</p> 3453 * StringUtils.padding(-2, 'e') = IndexOutOfBoundsException
1935 * 3454 * </pre>
1936 * <pre> 3455 * <p/>
1937 * StringUtils.join(null, *) = null 3456 * <p>Note: this method doesn't not support padding with
1938 * StringUtils.join([], *) = "" 3457 * <a href="http://www.unicode.org/glossary/#supplementary_character">Unicode Supplementary Characters</a>
1939 * StringUtils.join([null], *) = "" 3458 * as they require a pair of <code>char</code>s to be represented.
1940 * StringUtils.join(["a", "b", "c"], "--") = "a--b--c" 3459 * If you are needing to support full I18N of your applications
1941 * StringUtils.join(["a", "b", "c"], null) = "abc" 3460 * consider using {@link #repeat(String, int)} instead.
1942 * StringUtils.join(["a", "b", "c"], "") = "abc" 3461 * </p>
1943 * StringUtils.join([null, "", "a"], ',') = ",,a" 3462 *
1944 * </pre> 3463 * @param repeat number of times to repeat delim
1945 * 3464 * @param padChar character to repeat
1946 * @param array the array of values to join together, may be null 3465 * @return String with repeated character
1947 * @param separator the separator character to use, null treated as "" 3466 * @throws IndexOutOfBoundsException if <code>repeat &lt; 0</code>
1948 * @return the joined String, <code>null</code> if null array input 3467 * @see #repeat(String, int)
1949 */ 3468 */
1950 public static String join(Object[] array, String separator) { 3469 private static String padding(int repeat, char padChar) throws IndexOutOfBound sException
1951 if (array == null) { 3470 {
1952 return null; 3471 if (repeat < 0)
3472 {
3473 throw new IndexOutOfBoundsException("Cannot pad a negative amount: " + rep eat);
3474 }
3475 final char[] buf = new char[repeat];
3476 for (int i = 0; i < buf.length; i++)
3477 {
3478 buf[i] = padChar;
3479 }
3480 return new String(buf);
3481 }
3482
3483 /**
3484 * <p>Right pad a String with spaces (' ').</p>
3485 * <p/>
3486 * <p>The String is padded to the size of <code>size</code>.</p>
3487 * <p/>
3488 * <pre>
3489 * StringUtils.rightPad(null, *) = null
3490 * StringUtils.rightPad("", 3) = " "
3491 * StringUtils.rightPad("bat", 3) = "bat"
3492 * StringUtils.rightPad("bat", 5) = "bat "
3493 * StringUtils.rightPad("bat", 1) = "bat"
3494 * StringUtils.rightPad("bat", -1) = "bat"
3495 * </pre>
3496 *
3497 * @param str the String to pad out, may be null
3498 * @param size the size to pad to
3499 * @return right padded String or original String if no padding is necessary,
3500 * <code>null</code> if null String input
3501 */
3502 public static String rightPad(String str, int size)
3503 {
3504 return rightPad(str, size, ' ');
3505 }
3506
3507 /**
3508 * <p>Right pad a String with a specified character.</p>
3509 * <p/>
3510 * <p>The String is padded to the size of <code>size</code>.</p>
3511 * <p/>
3512 * <pre>
3513 * StringUtils.rightPad(null, *, *) = null
3514 * StringUtils.rightPad("", 3, 'z') = "zzz"
3515 * StringUtils.rightPad("bat", 3, 'z') = "bat"
3516 * StringUtils.rightPad("bat", 5, 'z') = "batzz"
3517 * StringUtils.rightPad("bat", 1, 'z') = "bat"
3518 * StringUtils.rightPad("bat", -1, 'z') = "bat"
3519 * </pre>
3520 *
3521 * @param str the String to pad out, may be null
3522 * @param size the size to pad to
3523 * @param padChar the character to pad with
3524 * @return right padded String or original String if no padding is necessary,
3525 * <code>null</code> if null String input
3526 * @since 2.0
3527 */
3528 public static String rightPad(String str, int size, char padChar)
3529 {
3530 if (str == null)
3531 {
3532 return null;
3533 }
3534 int pads = size - str.length();
3535 if (pads <= 0)
3536 {
3537 return str; // returns original String when possible
3538 }
3539 if (pads > PAD_LIMIT)
3540 {
3541 return rightPad(str, size, String.valueOf(padChar));
3542 }
3543 return str.concat(padding(pads, padChar));
3544 }
3545
3546 /**
3547 * <p>Right pad a String with a specified String.</p>
3548 * <p/>
3549 * <p>The String is padded to the size of <code>size</code>.</p>
3550 * <p/>
3551 * <pre>
3552 * StringUtils.rightPad(null, *, *) = null
3553 * StringUtils.rightPad("", 3, "z") = "zzz"
3554 * StringUtils.rightPad("bat", 3, "yz") = "bat"
3555 * StringUtils.rightPad("bat", 5, "yz") = "batyz"
3556 * StringUtils.rightPad("bat", 8, "yz") = "batyzyzy"
3557 * StringUtils.rightPad("bat", 1, "yz") = "bat"
3558 * StringUtils.rightPad("bat", -1, "yz") = "bat"
3559 * StringUtils.rightPad("bat", 5, null) = "bat "
3560 * StringUtils.rightPad("bat", 5, "") = "bat "
3561 * </pre>
3562 *
3563 * @param str the String to pad out, may be null
3564 * @param size the size to pad to
3565 * @param padStr the String to pad with, null or empty treated as single space
3566 * @return right padded String or original String if no padding is necessary,
3567 * <code>null</code> if null String input
3568 */
3569 public static String rightPad(String str, int size, String padStr)
3570 {
3571 if (str == null)
3572 {
3573 return null;
3574 }
3575 if (isEmpty(padStr))
3576 {
3577 padStr = " ";
3578 }
3579 int padLen = padStr.length();
3580 int strLen = str.length();
3581 int pads = size - strLen;
3582 if (pads <= 0)
3583 {
3584 return str; // returns original String when possible
3585 }
3586 if (padLen == 1 && pads <= PAD_LIMIT)
3587 {
3588 return rightPad(str, size, padStr.charAt(0));
3589 }
3590
3591 if (pads == padLen)
3592 {
3593 return str.concat(padStr);
3594 } else if (pads < padLen)
3595 {
3596 return str.concat(padStr.substring(0, pads));
3597 } else
3598 {
3599 char[] padding = new char[pads];
3600 char[] padChars = padStr.toCharArray();
3601 for (int i = 0; i < pads; i++)
3602 {
3603 padding[i] = padChars[i % padLen];
3604 }
3605 return str.concat(new String(padding));
3606 }
3607 }
3608
3609 /**
3610 * <p>Left pad a String with spaces (' ').</p>
3611 * <p/>
3612 * <p>The String is padded to the size of <code>size<code>.</p>
3613 * <p/>
3614 * <pre>
3615 * StringUtils.leftPad(null, *) = null
3616 * StringUtils.leftPad("", 3) = " "
3617 * StringUtils.leftPad("bat", 3) = "bat"
3618 * StringUtils.leftPad("bat", 5) = " bat"
3619 * StringUtils.leftPad("bat", 1) = "bat"
3620 * StringUtils.leftPad("bat", -1) = "bat"
3621 * </pre>
3622 *
3623 * @param str the String to pad out, may be null
3624 * @param size the size to pad to
3625 * @return left padded String or original String if no padding is necessary,
3626 * <code>null</code> if null String input
3627 */
3628 public static String leftPad(String str, int size)
3629 {
3630 return leftPad(str, size, ' ');
3631 }
3632
3633 /**
3634 * <p>Left pad a String with a specified character.</p>
3635 * <p/>
3636 * <p>Pad to a size of <code>size</code>.</p>
3637 * <p/>
3638 * <pre>
3639 * StringUtils.leftPad(null, *, *) = null
3640 * StringUtils.leftPad("", 3, 'z') = "zzz"
3641 * StringUtils.leftPad("bat", 3, 'z') = "bat"
3642 * StringUtils.leftPad("bat", 5, 'z') = "zzbat"
3643 * StringUtils.leftPad("bat", 1, 'z') = "bat"
3644 * StringUtils.leftPad("bat", -1, 'z') = "bat"
3645 * </pre>
3646 *
3647 * @param str the String to pad out, may be null
3648 * @param size the size to pad to
3649 * @param padChar the character to pad with
3650 * @return left padded String or original String if no padding is necessary,
3651 * <code>null</code> if null String input
3652 * @since 2.0
3653 */
3654 public static String leftPad(String str, int size, char padChar)
3655 {
3656 if (str == null)
3657 {
3658 return null;
3659 }
3660 int pads = size - str.length();
3661 if (pads <= 0)
3662 {
3663 return str; // returns original String when possible
3664 }
3665 if (pads > PAD_LIMIT)
3666 {
3667 return leftPad(str, size, String.valueOf(padChar));
3668 }
3669 return padding(pads, padChar).concat(str);
3670 }
3671
3672 /**
3673 * <p>Left pad a String with a specified String.</p>
3674 * <p/>
3675 * <p>Pad to a size of <code>size</code>.</p>
3676 * <p/>
3677 * <pre>
3678 * StringUtils.leftPad(null, *, *) = null
3679 * StringUtils.leftPad("", 3, "z") = "zzz"
3680 * StringUtils.leftPad("bat", 3, "yz") = "bat"
3681 * StringUtils.leftPad("bat", 5, "yz") = "yzbat"
3682 * StringUtils.leftPad("bat", 8, "yz") = "yzyzybat"
3683 * StringUtils.leftPad("bat", 1, "yz") = "bat"
3684 * StringUtils.leftPad("bat", -1, "yz") = "bat"
3685 * StringUtils.leftPad("bat", 5, null) = " bat"
3686 * StringUtils.leftPad("bat", 5, "") = " bat"
3687 * </pre>
3688 *
3689 * @param str the String to pad out, may be null
3690 * @param size the size to pad to
3691 * @param padStr the String to pad with, null or empty treated as single space
3692 * @return left padded String or original String if no padding is necessary,
3693 * <code>null</code> if null String input
3694 */
3695 public static String leftPad(String str, int size, String padStr)
3696 {
3697 if (str == null)
3698 {
3699 return null;
3700 }
3701 if (isEmpty(padStr))
3702 {
3703 padStr = " ";
3704 }
3705 int padLen = padStr.length();
3706 int strLen = str.length();
3707 int pads = size - strLen;
3708 if (pads <= 0)
3709 {
3710 return str; // returns original String when possible
3711 }
3712 if (padLen == 1 && pads <= PAD_LIMIT)
3713 {
3714 return leftPad(str, size, padStr.charAt(0));
3715 }
3716
3717 if (pads == padLen)
3718 {
3719 return padStr.concat(str);
3720 } else if (pads < padLen)
3721 {
3722 return padStr.substring(0, pads).concat(str);
3723 } else
3724 {
3725 char[] padding = new char[pads];
3726 char[] padChars = padStr.toCharArray();
3727 for (int i = 0; i < pads; i++)
3728 {
3729 padding[i] = padChars[i % padLen];
3730 }
3731 return new String(padding).concat(str);
3732 }
3733 }
3734
3735 /**
3736 * Gets a String's length or <code>0</code> if the String is <code>null</code> .
3737 *
3738 * @param str a String or <code>null</code>
3739 * @return String length or <code>0</code> if the String is <code>null</code>.
3740 * @since 2.4
3741 */
3742 public static int length(String str)
3743 {
3744 return str == null ? 0 : str.length();
3745 }
3746
3747 // Centering
3748 //-----------------------------------------------------------------------
3749
3750 /**
3751 * <p>Centers a String in a larger String of size <code>size</code>
3752 * using the space character (' ').<p>
3753 * <p/>
3754 * <p>If the size is less than the String length, the String is returned.
3755 * A <code>null</code> String returns <code>null</code>.
3756 * A negative size is treated as zero.</p>
3757 * <p/>
3758 * <p>Equivalent to <code>center(str, size, " ")</code>.</p>
3759 * <p/>
3760 * <pre>
3761 * StringUtils.center(null, *) = null
3762 * StringUtils.center("", 4) = " "
3763 * StringUtils.center("ab", -1) = "ab"
3764 * StringUtils.center("ab", 4) = " ab "
3765 * StringUtils.center("abcd", 2) = "abcd"
3766 * StringUtils.center("a", 4) = " a "
3767 * </pre>
3768 *
3769 * @param str the String to center, may be null
3770 * @param size the int size of new String, negative treated as zero
3771 * @return centered String, <code>null</code> if null String input
3772 */
3773 public static String center(String str, int size)
3774 {
3775 return center(str, size, ' ');
3776 }
3777
3778 /**
3779 * <p>Centers a String in a larger String of size <code>size</code>.
3780 * Uses a supplied character as the value to pad the String with.</p>
3781 * <p/>
3782 * <p>If the size is less than the String length, the String is returned.
3783 * A <code>null</code> String returns <code>null</code>.
3784 * A negative size is treated as zero.</p>
3785 * <p/>
3786 * <pre>
3787 * StringUtils.center(null, *, *) = null
3788 * StringUtils.center("", 4, ' ') = " "
3789 * StringUtils.center("ab", -1, ' ') = "ab"
3790 * StringUtils.center("ab", 4, ' ') = " ab"
3791 * StringUtils.center("abcd", 2, ' ') = "abcd"
3792 * StringUtils.center("a", 4, ' ') = " a "
3793 * StringUtils.center("a", 4, 'y') = "yayy"
3794 * </pre>
3795 *
3796 * @param str the String to center, may be null
3797 * @param size the int size of new String, negative treated as zero
3798 * @param padChar the character to pad the new String with
3799 * @return centered String, <code>null</code> if null String input
3800 * @since 2.0
3801 */
3802 public static String center(String str, int size, char padChar)
3803 {
3804 if (str == null || size <= 0)
3805 {
3806 return str;
3807 }
3808 int strLen = str.length();
3809 int pads = size - strLen;
3810 if (pads <= 0)
3811 {
3812 return str;
3813 }
3814 str = leftPad(str, strLen + pads / 2, padChar);
3815 str = rightPad(str, size, padChar);
3816 return str;
3817 }
3818
3819 /**
3820 * <p>Centers a String in a larger String of size <code>size</code>.
3821 * Uses a supplied String as the value to pad the String with.</p>
3822 * <p/>
3823 * <p>If the size is less than the String length, the String is returned.
3824 * A <code>null</code> String returns <code>null</code>.
3825 * A negative size is treated as zero.</p>
3826 * <p/>
3827 * <pre>
3828 * StringUtils.center(null, *, *) = null
3829 * StringUtils.center("", 4, " ") = " "
3830 * StringUtils.center("ab", -1, " ") = "ab"
3831 * StringUtils.center("ab", 4, " ") = " ab"
3832 * StringUtils.center("abcd", 2, " ") = "abcd"
3833 * StringUtils.center("a", 4, " ") = " a "
3834 * StringUtils.center("a", 4, "yz") = "yayz"
3835 * StringUtils.center("abc", 7, null) = " abc "
3836 * StringUtils.center("abc", 7, "") = " abc "
3837 * </pre>
3838 *
3839 * @param str the String to center, may be null
3840 * @param size the int size of new String, negative treated as zero
3841 * @param padStr the String to pad the new String with, must not be null or em pty
3842 * @return centered String, <code>null</code> if null String input
3843 * @throws IllegalArgumentException if padStr is <code>null</code> or empty
3844 */
3845 public static String center(String str, int size, String padStr)
3846 {
3847 if (str == null || size <= 0)
3848 {
3849 return str;
3850 }
3851 if (isEmpty(padStr))
3852 {
3853 padStr = " ";
3854 }
3855 int strLen = str.length();
3856 int pads = size - strLen;
3857 if (pads <= 0)
3858 {
3859 return str;
3860 }
3861 str = leftPad(str, strLen + pads / 2, padStr);
3862 str = rightPad(str, size, padStr);
3863 return str;
3864 }
3865
3866 // Case conversion
3867 //-----------------------------------------------------------------------
3868
3869 /**
3870 * <p>Converts a String to upper case as per {@link String#toUpperCase()}.</p>
3871 * <p/>
3872 * <p>A <code>null</code> input String returns <code>null</code>.</p>
3873 * <p/>
3874 * <pre>
3875 * StringUtils.upperCase(null) = null
3876 * StringUtils.upperCase("") = ""
3877 * StringUtils.upperCase("aBc") = "ABC"
3878 * </pre>
3879 *
3880 * @param str the String to upper case, may be null
3881 * @return the upper cased String, <code>null</code> if null String input
3882 */
3883 public static String upperCase(String str)
3884 {
3885 if (str == null)
3886 {
3887 return null;
3888 }
3889 return str.toUpperCase();
3890 }
3891
3892 /**
3893 * <p>Converts a String to lower case as per {@link String#toLowerCase()}.</p>
3894 * <p/>
3895 * <p>A <code>null</code> input String returns <code>null</code>.</p>
3896 * <p/>
3897 * <pre>
3898 * StringUtils.lowerCase(null) = null
3899 * StringUtils.lowerCase("") = ""
3900 * StringUtils.lowerCase("aBc") = "abc"
3901 * </pre>
3902 *
3903 * @param str the String to lower case, may be null
3904 * @return the lower cased String, <code>null</code> if null String input
3905 */
3906 public static String lowerCase(String str)
3907 {
3908 if (str == null)
3909 {
3910 return null;
3911 }
3912 return str.toLowerCase();
3913 }
3914
3915 /**
3916 * <p>Capitalizes a String changing the first letter to title case as
3917 * per {@link Character#toTitleCase(char)}. No other letters are changed.</p>
3918 * <p/>
3919 * <p>For a word based algorithm, see {@link WordUtils#capitalize(String)}.
3920 * A <code>null</code> input String returns <code>null</code>.</p>
3921 * <p/>
3922 * <pre>
3923 * StringUtils.capitalize(null) = null
3924 * StringUtils.capitalize("") = ""
3925 * StringUtils.capitalize("cat") = "Cat"
3926 * StringUtils.capitalize("cAt") = "CAt"
3927 * </pre>
3928 *
3929 * @param str the String to capitalize, may be null
3930 * @return the capitalized String, <code>null</code> if null String input
3931 * @see WordUtils#capitalize(String)
3932 * @see #uncapitalize(String)
3933 * @since 2.0
3934 */
3935 public static String capitalize(String str)
3936 {
3937 int strLen;
3938 if (str == null || (strLen = str.length()) == 0)
3939 {
3940 return str;
3941 }
3942 return new StringBuffer(strLen)
3943 .append(Character.toTitleCase(str.charAt(0)))
3944 .append(str.substring(1))
3945 .toString();
3946 }
3947
3948 /**
3949 * <p>Capitalizes a String changing the first letter to title case as
3950 * per {@link Character#toTitleCase(char)}. No other letters are changed.</p>
3951 *
3952 * @param str the String to capitalize, may be null
3953 * @return the capitalized String, <code>null</code> if null String input
3954 * @deprecated Use the standardly named {@link #capitalize(String)}.
3955 * Method will be removed in Commons Lang 3.0.
3956 */
3957 public static String capitalise(String str)
3958 {
3959 return capitalize(str);
3960 }
3961
3962 /**
3963 * <p>Uncapitalizes a String changing the first letter to title case as
3964 * per {@link Character#toLowerCase(char)}. No other letters are changed.</p>
3965 * <p/>
3966 * <p>For a word based algorithm, see {@link WordUtils#uncapitalize(String)}.
3967 * A <code>null</code> input String returns <code>null</code>.</p>
3968 * <p/>
3969 * <pre>
3970 * StringUtils.uncapitalize(null) = null
3971 * StringUtils.uncapitalize("") = ""
3972 * StringUtils.uncapitalize("Cat") = "cat"
3973 * StringUtils.uncapitalize("CAT") = "cAT"
3974 * </pre>
3975 *
3976 * @param str the String to uncapitalize, may be null
3977 * @return the uncapitalized String, <code>null</code> if null String input
3978 * @see WordUtils#uncapitalize(String)
3979 * @see #capitalize(String)
3980 * @since 2.0
3981 */
3982 public static String uncapitalize(String str)
3983 {
3984 int strLen;
3985 if (str == null || (strLen = str.length()) == 0)
3986 {
3987 return str;
3988 }
3989 return new StringBuffer(strLen)
3990 .append(Character.toLowerCase(str.charAt(0)))
3991 .append(str.substring(1))
3992 .toString();
3993 }
3994
3995 /**
3996 * <p>Uncapitalizes a String changing the first letter to title case as
3997 * per {@link Character#toLowerCase(char)}. No other letters are changed.</p>
3998 *
3999 * @param str the String to uncapitalize, may be null
4000 * @return the uncapitalized String, <code>null</code> if null String input
4001 * @deprecated Use the standardly named {@link #uncapitalize(String)}.
4002 * Method will be removed in Commons Lang 3.0.
4003 */
4004 public static String uncapitalise(String str)
4005 {
4006 return uncapitalize(str);
4007 }
4008
4009 /**
4010 * <p>Swaps the case of a String changing upper and title case to
4011 * lower case, and lower case to upper case.</p>
4012 * <p/>
4013 * <ul>
4014 * <li>Upper case character converts to Lower case</li>
4015 * <li>Title case character converts to Lower case</li>
4016 * <li>Lower case character converts to Upper case</li>
4017 * </ul>
4018 * <p/>
4019 * <p>For a word based algorithm, see {@link WordUtils#swapCase(String)}.
4020 * A <code>null</code> input String returns <code>null</code>.</p>
4021 * <p/>
4022 * <pre>
4023 * StringUtils.swapCase(null) = null
4024 * StringUtils.swapCase("") = ""
4025 * StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
4026 * </pre>
4027 * <p/>
4028 * <p>NOTE: This method changed in Lang version 2.0.
4029 * It no longer performs a word based algorithm.
4030 * If you only use ASCII, you will notice no change.
4031 * That functionality is available in WordUtils.</p>
4032 *
4033 * @param str the String to swap case, may be null
4034 * @return the changed String, <code>null</code> if null String input
4035 */
4036 public static String swapCase(String str)
4037 {
4038 int strLen;
4039 if (str == null || (strLen = str.length()) == 0)
4040 {
4041 return str;
4042 }
4043 StringBuffer buffer = new StringBuffer(strLen);
4044
4045 char ch = 0;
4046 for (int i = 0; i < strLen; i++)
4047 {
4048 ch = str.charAt(i);
4049 if (Character.isUpperCase(ch))
4050 {
4051 ch = Character.toLowerCase(ch);
4052 } else if (Character.isTitleCase(ch))
4053 {
4054 ch = Character.toLowerCase(ch);
4055 } else if (Character.isLowerCase(ch))
4056 {
4057 ch = Character.toUpperCase(ch);
4058 }
4059 buffer.append(ch);
4060 }
4061 return buffer.toString();
4062 }
4063
4064 // Count matches
4065 //-----------------------------------------------------------------------
4066
4067 /**
4068 * <p>Counts how many times the substring appears in the larger String.</p>
4069 * <p/>
4070 * <p>A <code>null</code> or empty ("") String input returns <code>0</code>.</ p>
4071 * <p/>
4072 * <pre>
4073 * StringUtils.countMatches(null, *) = 0
4074 * StringUtils.countMatches("", *) = 0
4075 * StringUtils.countMatches("abba", null) = 0
4076 * StringUtils.countMatches("abba", "") = 0
4077 * StringUtils.countMatches("abba", "a") = 2
4078 * StringUtils.countMatches("abba", "ab") = 1
4079 * StringUtils.countMatches("abba", "xxx") = 0
4080 * </pre>
4081 *
4082 * @param str the String to check, may be null
4083 * @param sub the substring to count, may be null
4084 * @return the number of occurrences, 0 if either String is <code>null</code>
4085 */
4086 public static int countMatches(String str, String sub)
4087 {
4088 if (isEmpty(str) || isEmpty(sub))
4089 {
4090 return 0;
4091 }
4092 int count = 0;
4093 int idx = 0;
4094 while ((idx = str.indexOf(sub, idx)) != -1)
4095 {
4096 count++;
4097 idx += sub.length();
4098 }
4099 return count;
4100 }
4101
4102 // Character Tests
4103 //-----------------------------------------------------------------------
4104
4105 /**
4106 * <p>Checks if the String contains only unicode letters.</p>
4107 * <p/>
4108 * <p><code>null</code> will return <code>false</code>.
4109 * An empty String ("") will return <code>true</code>.</p>
4110 * <p/>
4111 * <pre>
4112 * StringUtils.isAlpha(null) = false
4113 * StringUtils.isAlpha("") = true
4114 * StringUtils.isAlpha(" ") = false
4115 * StringUtils.isAlpha("abc") = true
4116 * StringUtils.isAlpha("ab2c") = false
4117 * StringUtils.isAlpha("ab-c") = false
4118 * </pre>
4119 *
4120 * @param str the String to check, may be null
4121 * @return <code>true</code> if only contains letters, and is non-null
4122 */
4123 public static boolean isAlpha(String str)
4124 {
4125 if (str == null)
4126 {
4127 return false;
4128 }
4129 int sz = str.length();
4130 for (int i = 0; i < sz; i++)
4131 {
4132 if (Character.isLetter(str.charAt(i)) == false)
4133 {
4134 return false;
4135 }
4136 }
4137 return true;
4138 }
4139
4140 /**
4141 * <p>Checks if the String contains only unicode letters and
4142 * space (' ').</p>
4143 * <p/>
4144 * <p><code>null</code> will return <code>false</code>
4145 * An empty String ("") will return <code>true</code>.</p>
4146 * <p/>
4147 * <pre>
4148 * StringUtils.isAlphaSpace(null) = false
4149 * StringUtils.isAlphaSpace("") = true
4150 * StringUtils.isAlphaSpace(" ") = true
4151 * StringUtils.isAlphaSpace("abc") = true
4152 * StringUtils.isAlphaSpace("ab c") = true
4153 * StringUtils.isAlphaSpace("ab2c") = false
4154 * StringUtils.isAlphaSpace("ab-c") = false
4155 * </pre>
4156 *
4157 * @param str the String to check, may be null
4158 * @return <code>true</code> if only contains letters and space,
4159 * and is non-null
4160 */
4161 public static boolean isAlphaSpace(String str)
4162 {
4163 if (str == null)
4164 {
4165 return false;
4166 }
4167 int sz = str.length();
4168 for (int i = 0; i < sz; i++)
4169 {
4170 if ((Character.isLetter(str.charAt(i)) == false) && (str.charAt(i) != ' ') )
4171 {
4172 return false;
4173 }
4174 }
4175 return true;
4176 }
4177
4178 /**
4179 * <p>Checks if the String contains only unicode letters or digits.</p>
4180 * <p/>
4181 * <p><code>null</code> will return <code>false</code>.
4182 * An empty String ("") will return <code>true</code>.</p>
4183 * <p/>
4184 * <pre>
4185 * StringUtils.isAlphanumeric(null) = false
4186 * StringUtils.isAlphanumeric("") = true
4187 * StringUtils.isAlphanumeric(" ") = false
4188 * StringUtils.isAlphanumeric("abc") = true
4189 * StringUtils.isAlphanumeric("ab c") = false
4190 * StringUtils.isAlphanumeric("ab2c") = true
4191 * StringUtils.isAlphanumeric("ab-c") = false
4192 * </pre>
4193 *
4194 * @param str the String to check, may be null
4195 * @return <code>true</code> if only contains letters or digits,
4196 * and is non-null
4197 */
4198 public static boolean isAlphanumeric(String str)
4199 {
4200 if (str == null)
4201 {
4202 return false;
4203 }
4204 int sz = str.length();
4205 for (int i = 0; i < sz; i++)
4206 {
4207 if (Character.isLetterOrDigit(str.charAt(i)) == false)
4208 {
4209 return false;
4210 }
4211 }
4212 return true;
4213 }
4214
4215 /**
4216 * <p>Checks if the String contains only unicode letters, digits
4217 * or space (<code>' '</code>).</p>
4218 * <p/>
4219 * <p><code>null</code> will return <code>false</code>.
4220 * An empty String ("") will return <code>true</code>.</p>
4221 * <p/>
4222 * <pre>
4223 * StringUtils.isAlphanumeric(null) = false
4224 * StringUtils.isAlphanumeric("") = true
4225 * StringUtils.isAlphanumeric(" ") = true
4226 * StringUtils.isAlphanumeric("abc") = true
4227 * StringUtils.isAlphanumeric("ab c") = true
4228 * StringUtils.isAlphanumeric("ab2c") = true
4229 * StringUtils.isAlphanumeric("ab-c") = false
4230 * </pre>
4231 *
4232 * @param str the String to check, may be null
4233 * @return <code>true</code> if only contains letters, digits or space,
4234 * and is non-null
4235 */
4236 public static boolean isAlphanumericSpace(String str)
4237 {
4238 if (str == null)
4239 {
4240 return false;
4241 }
4242 int sz = str.length();
4243 for (int i = 0; i < sz; i++)
4244 {
4245 if ((Character.isLetterOrDigit(str.charAt(i)) == false) && (str.charAt(i) != ' '))
4246 {
4247 return false;
4248 }
4249 }
4250 return true;
4251 }
4252
4253 /**
4254 * <p>Checks if the string contains only ASCII printable characters.</p>
4255 * <p/>
4256 * <p><code>null</code> will return <code>false</code>.
4257 * An empty String ("") will return <code>true</code>.</p>
4258 * <p/>
4259 * <pre>
4260 * StringUtils.isAsciiPrintable(null) = false
4261 * StringUtils.isAsciiPrintable("") = true
4262 * StringUtils.isAsciiPrintable(" ") = true
4263 * StringUtils.isAsciiPrintable("Ceki") = true
4264 * StringUtils.isAsciiPrintable("ab2c") = true
4265 * StringUtils.isAsciiPrintable("!ab-c~") = true
4266 * StringUtils.isAsciiPrintable("\u0020") = true
4267 * StringUtils.isAsciiPrintable("\u0021") = true
4268 * StringUtils.isAsciiPrintable("\u007e") = true
4269 * StringUtils.isAsciiPrintable("\u007f") = false
4270 * StringUtils.isAsciiPrintable("Ceki G\u00fclc\u00fc") = false
4271 * </pre>
4272 *
4273 * @param str the string to check, may be null
4274 * @return <code>true</code> if every character is in the range
4275 * 32 thru 126
4276 * @since 2.1
4277 */
4278 public static boolean isAsciiPrintable(String str)
4279 {
4280 if (str == null)
4281 {
4282 return false;
4283 }
4284 int sz = str.length();
4285 for (int i = 0; i < sz; i++)
4286 {
4287 if (CharUtils.isAsciiPrintable(str.charAt(i)) == false)
4288 {
4289 return false;
4290 }
4291 }
4292 return true;
4293 }
4294
4295 /**
4296 * <p>Checks if the String contains only unicode digits.
4297 * A decimal point is not a unicode digit and returns false.</p>
4298 * <p/>
4299 * <p><code>null</code> will return <code>false</code>.
4300 * An empty String ("") will return <code>true</code>.</p>
4301 * <p/>
4302 * <pre>
4303 * StringUtils.isNumeric(null) = false
4304 * StringUtils.isNumeric("") = true
4305 * StringUtils.isNumeric(" ") = false
4306 * StringUtils.isNumeric("123") = true
4307 * StringUtils.isNumeric("12 3") = false
4308 * StringUtils.isNumeric("ab2c") = false
4309 * StringUtils.isNumeric("12-3") = false
4310 * StringUtils.isNumeric("12.3") = false
4311 * </pre>
4312 *
4313 * @param str the String to check, may be null
4314 * @return <code>true</code> if only contains digits, and is non-null
4315 */
4316 public static boolean isNumeric(String str)
4317 {
4318 if (str == null)
4319 {
4320 return false;
4321 }
4322 int sz = str.length();
4323 for (int i = 0; i < sz; i++)
4324 {
4325 if (Character.isDigit(str.charAt(i)) == false)
4326 {
4327 return false;
4328 }
4329 }
4330 return true;
4331 }
4332
4333 /**
4334 * <p>Checks if the String contains only unicode digits or space
4335 * (<code>' '</code>).
4336 * A decimal point is not a unicode digit and returns false.</p>
4337 * <p/>
4338 * <p><code>null</code> will return <code>false</code>.
4339 * An empty String ("") will return <code>true</code>.</p>
4340 * <p/>
4341 * <pre>
4342 * StringUtils.isNumeric(null) = false
4343 * StringUtils.isNumeric("") = true
4344 * StringUtils.isNumeric(" ") = true
4345 * StringUtils.isNumeric("123") = true
4346 * StringUtils.isNumeric("12 3") = true
4347 * StringUtils.isNumeric("ab2c") = false
4348 * StringUtils.isNumeric("12-3") = false
4349 * StringUtils.isNumeric("12.3") = false
4350 * </pre>
4351 *
4352 * @param str the String to check, may be null
4353 * @return <code>true</code> if only contains digits or space,
4354 * and is non-null
4355 */
4356 public static boolean isNumericSpace(String str)
4357 {
4358 if (str == null)
4359 {
4360 return false;
4361 }
4362 int sz = str.length();
4363 for (int i = 0; i < sz; i++)
4364 {
4365 if ((Character.isDigit(str.charAt(i)) == false) && (str.charAt(i) != ' '))
4366 {
4367 return false;
4368 }
4369 }
4370 return true;
4371 }
4372
4373 /**
4374 * <p>Checks if the String contains only whitespace.</p>
4375 * <p/>
4376 * <p><code>null</code> will return <code>false</code>.
4377 * An empty String ("") will return <code>true</code>.</p>
4378 * <p/>
4379 * <pre>
4380 * StringUtils.isWhitespace(null) = false
4381 * StringUtils.isWhitespace("") = true
4382 * StringUtils.isWhitespace(" ") = true
4383 * StringUtils.isWhitespace("abc") = false
4384 * StringUtils.isWhitespace("ab2c") = false
4385 * StringUtils.isWhitespace("ab-c") = false
4386 * </pre>
4387 *
4388 * @param str the String to check, may be null
4389 * @return <code>true</code> if only contains whitespace, and is non-null
4390 * @since 2.0
4391 */
4392 public static boolean isWhitespace(String str)
4393 {
4394 if (str == null)
4395 {
4396 return false;
4397 }
4398 int sz = str.length();
4399 for (int i = 0; i < sz; i++)
4400 {
4401 if ((Character.isWhitespace(str.charAt(i)) == false))
4402 {
4403 return false;
4404 }
4405 }
4406 return true;
4407 }
4408
4409 // Defaults
4410 //-----------------------------------------------------------------------
4411
4412 /**
4413 * <p>Returns either the passed in String,
4414 * or if the String is <code>null</code>, an empty String ("").</p>
4415 * <p/>
4416 * <pre>
4417 * StringUtils.defaultString(null) = ""
4418 * StringUtils.defaultString("") = ""
4419 * StringUtils.defaultString("bat") = "bat"
4420 * </pre>
4421 *
4422 * @param str the String to check, may be null
4423 * @return the passed in String, or the empty String if it
4424 * was <code>null</code>
4425 * @see ObjectUtils#toString(Object)
4426 * @see String#valueOf(Object)
4427 */
4428 public static String defaultString(String str)
4429 {
4430 return str == null ? EMPTY : str;
4431 }
4432
4433 /**
4434 * <p>Returns either the passed in String, or if the String is
4435 * <code>null</code>, the value of <code>defaultStr</code>.</p>
4436 * <p/>
4437 * <pre>
4438 * StringUtils.defaultString(null, "NULL") = "NULL"
4439 * StringUtils.defaultString("", "NULL") = ""
4440 * StringUtils.defaultString("bat", "NULL") = "bat"
4441 * </pre>
4442 *
4443 * @param str the String to check, may be null
4444 * @param defaultStr the default String to return
4445 * if the input is <code>null</code>, may be null
4446 * @return the passed in String, or the default if it was <code>null</code>
4447 * @see ObjectUtils#toString(Object, String)
4448 * @see String#valueOf(Object)
4449 */
4450 public static String defaultString(String str, String defaultStr)
4451 {
4452 return str == null ? defaultStr : str;
4453 }
4454
4455 /**
4456 * <p>Returns either the passed in String, or if the String is
4457 * empty or <code>null</code>, the value of <code>defaultStr</code>.</p>
4458 * <p/>
4459 * <pre>
4460 * StringUtils.defaultIfEmpty(null, "NULL") = "NULL"
4461 * StringUtils.defaultIfEmpty("", "NULL") = "NULL"
4462 * StringUtils.defaultIfEmpty("bat", "NULL") = "bat"
4463 * </pre>
4464 *
4465 * @param str the String to check, may be null
4466 * @param defaultStr the default String to return
4467 * if the input is empty ("") or <code>null</code>, may be n ull
4468 * @return the passed in String, or the default
4469 * @see StringUtils#defaultString(String, String)
4470 */
4471 public static String defaultIfEmpty(String str, String defaultStr)
4472 {
4473 return StringUtils.isEmpty(str) ? defaultStr : str;
4474 }
4475
4476 // Reversing
4477 //-----------------------------------------------------------------------
4478
4479 /**
4480 * <p>Reverses a String as per {@link StringBuffer#reverse()}.</p>
4481 * <p/>
4482 * <p>A <code>null</code> String returns <code>null</code>.</p>
4483 * <p/>
4484 * <pre>
4485 * StringUtils.reverse(null) = null
4486 * StringUtils.reverse("") = ""
4487 * StringUtils.reverse("bat") = "tab"
4488 * </pre>
4489 *
4490 * @param str the String to reverse, may be null
4491 * @return the reversed String, <code>null</code> if null String input
4492 */
4493 public static String reverse(String str)
4494 {
4495 if (str == null)
4496 {
4497 return null;
4498 }
4499 return new StringBuffer(str).reverse().toString();
4500 }
4501
4502 // Abbreviating
4503 //-----------------------------------------------------------------------
4504
4505 /**
4506 * <p>Abbreviates a String using ellipses. This will turn
4507 * "Now is the time for all good men" into "Now is the time for..."</p>
4508 * <p/>
4509 * <p>Specifically:
4510 * <ul>
4511 * <li>If <code>str</code> is less than <code>maxWidth</code> characters
4512 * long, return it.</li>
4513 * <li>Else abbreviate it to <code>(substring(str, 0, max-3) + "...")</code>.< /li>
4514 * <li>If <code>maxWidth</code> is less than <code>4</code>, throw an
4515 * <code>IllegalArgumentException</code>.</li>
4516 * <li>In no case will it return a String of length greater than
4517 * <code>maxWidth</code>.</li>
4518 * </ul>
4519 * </p>
4520 * <p/>
4521 * <pre>
4522 * StringUtils.abbreviate(null, *) = null
4523 * StringUtils.abbreviate("", 4) = ""
4524 * StringUtils.abbreviate("abcdefg", 6) = "abc..."
4525 * StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
4526 * StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
4527 * StringUtils.abbreviate("abcdefg", 4) = "a..."
4528 * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException
4529 * </pre>
4530 *
4531 * @param str the String to check, may be null
4532 * @param maxWidth maximum length of result String, must be at least 4
4533 * @return abbreviated String, <code>null</code> if null String input
4534 * @throws IllegalArgumentException if the width is too small
4535 * @since 2.0
4536 */
4537 public static String abbreviate(String str, int maxWidth)
4538 {
4539 return abbreviate(str, 0, maxWidth);
4540 }
4541
4542 /**
4543 * <p>Abbreviates a String using ellipses. This will turn
4544 * "Now is the time for all good men" into "...is the time for..."</p>
4545 * <p/>
4546 * <p>Works like <code>abbreviate(String, int)</code>, but allows you to speci fy
4547 * a "left edge" offset. Note that this left edge is not necessarily going to
4548 * be the leftmost character in the result, or the first character following t he
4549 * ellipses, but it will appear somewhere in the result.
4550 * <p/>
4551 * <p>In no case will it return a String of length greater than
4552 * <code>maxWidth</code>.</p>
4553 * <p/>
4554 * <pre>
4555 * StringUtils.abbreviate(null, *, *) = null
4556 * StringUtils.abbreviate("", 0, 4) = ""
4557 * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
4558 * StringUtils.abbreviate("abcdefghijklmno", 0, 10) = "abcdefg..."
4559 * StringUtils.abbreviate("abcdefghijklmno", 1, 10) = "abcdefg..."
4560 * StringUtils.abbreviate("abcdefghijklmno", 4, 10) = "abcdefg..."
4561 * StringUtils.abbreviate("abcdefghijklmno", 5, 10) = "...fghi..."
4562 * StringUtils.abbreviate("abcdefghijklmno", 6, 10) = "...ghij..."
4563 * StringUtils.abbreviate("abcdefghijklmno", 8, 10) = "...ijklmno"
4564 * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
4565 * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
4566 * StringUtils.abbreviate("abcdefghij", 0, 3) = IllegalArgumentExceptio n
4567 * StringUtils.abbreviate("abcdefghij", 5, 6) = IllegalArgumentExceptio n
4568 * </pre>
4569 *
4570 * @param str the String to check, may be null
4571 * @param offset left edge of source String
4572 * @param maxWidth maximum length of result String, must be at least 4
4573 * @return abbreviated String, <code>null</code> if null String input
4574 * @throws IllegalArgumentException if the width is too small
4575 * @since 2.0
4576 */
4577 public static String abbreviate(String str, int offset, int maxWidth)
4578 {
4579 if (str == null)
4580 {
4581 return null;
4582 }
4583 if (maxWidth < 4)
4584 {
4585 throw new IllegalArgumentException("Minimum abbreviation width is 4");
4586 }
4587 if (str.length() <= maxWidth)
4588 {
4589 return str;
4590 }
4591 if (offset > str.length())
4592 {
4593 offset = str.length();
4594 }
4595 if ((str.length() - offset) < (maxWidth - 3))
4596 {
4597 offset = str.length() - (maxWidth - 3);
4598 }
4599 if (offset <= 4)
4600 {
4601 return str.substring(0, maxWidth - 3) + "...";
4602 }
4603 if (maxWidth < 7)
4604 {
4605 throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
4606 }
4607 if ((offset + (maxWidth - 3)) < str.length())
4608 {
4609 return "..." + abbreviate(str.substring(offset), maxWidth - 3);
4610 }
4611 return "..." + str.substring(str.length() - (maxWidth - 3));
4612 }
4613
4614 // Difference
4615 //-----------------------------------------------------------------------
4616
4617 /**
4618 * <p>Compares two Strings, and returns the portion where they differ.
4619 * (More precisely, return the remainder of the second String,
4620 * starting from where it's different from the first.)</p>
4621 * <p/>
4622 * <p>For example,
4623 * <code>difference("i am a machine", "i am a robot") -> "robot"</code>.</p>
4624 * <p/>
4625 * <pre>
4626 * StringUtils.difference(null, null) = null
4627 * StringUtils.difference("", "") = ""
4628 * StringUtils.difference("", "abc") = "abc"
4629 * StringUtils.difference("abc", "") = ""
4630 * StringUtils.difference("abc", "abc") = ""
4631 * StringUtils.difference("ab", "abxyz") = "xyz"
4632 * StringUtils.difference("abcde", "abxyz") = "xyz"
4633 * StringUtils.difference("abcde", "xyz") = "xyz"
4634 * </pre>
4635 *
4636 * @param str1 the first String, may be null
4637 * @param str2 the second String, may be null
4638 * @return the portion of str2 where it differs from str1; returns the
4639 * empty String if they are equal
4640 * @since 2.0
4641 */
4642 public static String difference(String str1, String str2)
4643 {
4644 if (str1 == null)
4645 {
4646 return str2;
4647 }
4648 if (str2 == null)
4649 {
4650 return str1;
4651 }
4652 int at = indexOfDifference(str1, str2);
4653 if (at == -1)
4654 {
4655 return EMPTY;
4656 }
4657 return str2.substring(at);
4658 }
4659
4660 /**
4661 * <p>Compares two Strings, and returns the index at which the
4662 * Strings begin to differ.</p>
4663 * <p/>
4664 * <p>For example,
4665 * <code>indexOfDifference("i am a machine", "i am a robot") -> 7</code></p>
4666 * <p/>
4667 * <pre>
4668 * StringUtils.indexOfDifference(null, null) = -1
4669 * StringUtils.indexOfDifference("", "") = -1
4670 * StringUtils.indexOfDifference("", "abc") = 0
4671 * StringUtils.indexOfDifference("abc", "") = 0
4672 * StringUtils.indexOfDifference("abc", "abc") = -1
4673 * StringUtils.indexOfDifference("ab", "abxyz") = 2
4674 * StringUtils.indexOfDifference("abcde", "abxyz") = 2
4675 * StringUtils.indexOfDifference("abcde", "xyz") = 0
4676 * </pre>
4677 *
4678 * @param str1 the first String, may be null
4679 * @param str2 the second String, may be null
4680 * @return the index where str2 and str1 begin to differ; -1 if they are equal
4681 * @since 2.0
4682 */
4683 public static int indexOfDifference(String str1, String str2)
4684 {
4685 if (str1 == str2)
4686 {
4687 return -1;
4688 }
4689 if (str1 == null || str2 == null)
4690 {
4691 return 0;
4692 }
4693 int i;
4694 for (i = 0; i < str1.length() && i < str2.length(); ++i)
4695 {
4696 if (str1.charAt(i) != str2.charAt(i))
4697 {
4698 break;
4699 }
4700 }
4701 if (i < str2.length() || i < str1.length())
4702 {
4703 return i;
4704 }
4705 return -1;
4706 }
4707
4708 /**
4709 * <p>Compares all Strings in an array and returns the index at which the
4710 * Strings begin to differ.</p>
4711 * <p/>
4712 * <p>For example,
4713 * <code>indexOfDifference(new String[] {"i am a machine", "i am a robot"}) -> 7</code></p>
4714 * <p/>
4715 * <pre>
4716 * StringUtils.indexOfDifference(null) = -1
4717 * StringUtils.indexOfDifference(new String[] {}) = -1
4718 * StringUtils.indexOfDifference(new String[] {"abc"}) = -1
4719 * StringUtils.indexOfDifference(new String[] {null, null}) = -1
4720 * StringUtils.indexOfDifference(new String[] {"", ""}) = -1
4721 * StringUtils.indexOfDifference(new String[] {"", null}) = 0
4722 * StringUtils.indexOfDifference(new String[] {"abc", null, null}) = 0
4723 * StringUtils.indexOfDifference(new String[] {null, null, "abc"}) = 0
4724 * StringUtils.indexOfDifference(new String[] {"", "abc"}) = 0
4725 * StringUtils.indexOfDifference(new String[] {"abc", ""}) = 0
4726 * StringUtils.indexOfDifference(new String[] {"abc", "abc"}) = -1
4727 * StringUtils.indexOfDifference(new String[] {"abc", "a"}) = 1
4728 * StringUtils.indexOfDifference(new String[] {"ab", "abxyz"}) = 2
4729 * StringUtils.indexOfDifference(new String[] {"abcde", "abxyz"}) = 2
4730 * StringUtils.indexOfDifference(new String[] {"abcde", "xyz"}) = 0
4731 * StringUtils.indexOfDifference(new String[] {"xyz", "abcde"}) = 0
4732 * StringUtils.indexOfDifference(new String[] {"i am a machine", "i am a robot "}) = 7
4733 * </pre>
4734 *
4735 * @param strs array of strings, entries may be null
4736 * @return the index where the strings begin to differ; -1 if they are all equ al
4737 * @since 2.4
4738 */
4739 public static int indexOfDifference(String[] strs)
4740 {
4741 if (strs == null || strs.length <= 1)
4742 {
4743 return -1;
4744 }
4745 boolean anyStringNull = false;
4746 boolean allStringsNull = true;
4747 int arrayLen = strs.length;
4748 int shortestStrLen = Integer.MAX_VALUE;
4749 int longestStrLen = 0;
4750
4751 // find the min and max string lengths; this avoids checking to make
4752 // sure we are not exceeding the length of the string each time through
4753 // the bottom loop.
4754 for (int i = 0; i < arrayLen; i++)
4755 {
4756 if (strs[i] == null)
4757 {
4758 anyStringNull = true;
4759 shortestStrLen = 0;
4760 } else
4761 {
4762 allStringsNull = false;
4763 shortestStrLen = Math.min(strs[i].length(), shortestStrLen);
4764 longestStrLen = Math.max(strs[i].length(), longestStrLen);
4765 }
4766 }
4767
4768 // handle lists containing all nulls or all empty strings
4769 if (allStringsNull || (longestStrLen == 0 && !anyStringNull))
4770 {
4771 return -1;
4772 }
4773
4774 // handle lists containing some nulls or some empty strings
4775 if (shortestStrLen == 0)
4776 {
4777 return 0;
4778 }
4779
4780 // find the position with the first difference across all strings
4781 int firstDiff = -1;
4782 for (int stringPos = 0; stringPos < shortestStrLen; stringPos++)
4783 {
4784 char comparisonChar = strs[0].charAt(stringPos);
4785 for (int arrayPos = 1; arrayPos < arrayLen; arrayPos++)
4786 {
4787 if (strs[arrayPos].charAt(stringPos) != comparisonChar)
4788 {
4789 firstDiff = stringPos;
4790 break;
1953 } 4791 }
1954 return join(array, separator, 0, array.length); 4792 }
1955 } 4793 if (firstDiff != -1)
1956 4794 {
1957 /** 4795 break;
1958 * <p>Joins the elements of the provided array into a single String 4796 }
1959 * containing the provided list of elements.</p> 4797 }
1960 * 4798
1961 * <p>No delimiter is added before or after the list. 4799 if (firstDiff == -1 && shortestStrLen != longestStrLen)
1962 * A <code>null</code> separator is the same as an empty String (""). 4800 {
1963 * Null objects or empty strings within the array are represented by 4801 // we compared all of the characters up to the length of the
1964 * empty strings.</p> 4802 // shortest string and didn't find a match, but the string lengths
1965 * 4803 // vary, so return the length of the shortest string.
1966 * <pre> 4804 return shortestStrLen;
1967 * StringUtils.join(null, *) = null 4805 }
1968 * StringUtils.join([], *) = "" 4806 return firstDiff;
1969 * StringUtils.join([null], *) = "" 4807 }
1970 * StringUtils.join(["a", "b", "c"], "--") = "a--b--c" 4808
1971 * StringUtils.join(["a", "b", "c"], null) = "abc" 4809 /**
1972 * StringUtils.join(["a", "b", "c"], "") = "abc" 4810 * <p>Compares all Strings in an array and returns the initial sequence of
1973 * StringUtils.join([null, "", "a"], ',') = ",,a" 4811 * characters that is common to all of them.</p>
1974 * </pre> 4812 * <p/>
1975 * 4813 * <p>For example,
1976 * @param array the array of values to join together, may be null 4814 * <code>getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) -> " i am a "</code></p>
1977 * @param separator the separator character to use, null treated as "" 4815 * <p/>
1978 * @param startIndex the first index to start joining from. It is 4816 * <pre>
1979 * an error to pass in an end index past the end of the array 4817 * StringUtils.getCommonPrefix(null) = ""
1980 * @param endIndex the index to stop joining from (exclusive). It is 4818 * StringUtils.getCommonPrefix(new String[] {}) = ""
1981 * an error to pass in an end index past the end of the array 4819 * StringUtils.getCommonPrefix(new String[] {"abc"}) = "abc"
1982 * @return the joined String, <code>null</code> if null array input 4820 * StringUtils.getCommonPrefix(new String[] {null, null}) = ""
1983 */ 4821 * StringUtils.getCommonPrefix(new String[] {"", ""}) = ""
1984 public static String join(Object[] array, String separator, int startIndex, int endIndex) { 4822 * StringUtils.getCommonPrefix(new String[] {"", null}) = ""
1985 if (array == null) { 4823 * StringUtils.getCommonPrefix(new String[] {"abc", null, null}) = ""
1986 return null; 4824 * StringUtils.getCommonPrefix(new String[] {null, null, "abc"}) = ""
1987 } 4825 * StringUtils.getCommonPrefix(new String[] {"", "abc"}) = ""
1988 if (separator == null) { 4826 * StringUtils.getCommonPrefix(new String[] {"abc", ""}) = ""
1989 separator = EMPTY; 4827 * StringUtils.getCommonPrefix(new String[] {"abc", "abc"}) = "abc"
1990 } 4828 * StringUtils.getCommonPrefix(new String[] {"abc", "a"}) = "a"
1991 4829 * StringUtils.getCommonPrefix(new String[] {"ab", "abxyz"}) = "ab"
1992 // endIndex - startIndex > 0: Len = NofStrings *(len(firstString) + le n(separator)) 4830 * StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"
1993 // (Assuming that all Strings are roughly equally long) 4831 * StringUtils.getCommonPrefix(new String[] {"abcde", "xyz"}) = ""
1994 int bufSize = (endIndex - startIndex); 4832 * StringUtils.getCommonPrefix(new String[] {"xyz", "abcde"}) = ""
1995 if (bufSize <= 0) { 4833 * StringUtils.getCommonPrefix(new String[] {"i am a machine", "i am a robot"} ) = "i am a "
1996 return EMPTY; 4834 * </pre>
1997 } 4835 *
1998 4836 * @param strs array of String objects, entries may be null
1999 bufSize *= ((array[startIndex] == null ? 16 : array[startIndex].toString ().length()) 4837 * @return the initial sequence of characters that are common to all Strings
2000 + separator.length()); 4838 * in the array; empty String if the array is null, the elements are all null
2001 4839 * or if there is no common prefix.
2002 StringBuffer buf = new StringBuffer(bufSize); 4840 * @since 2.4
2003 4841 */
2004 for (int i = startIndex; i < endIndex; i++) { 4842 public static String getCommonPrefix(String[] strs)
2005 if (i > startIndex) { 4843 {
2006 buf.append(separator); 4844 if (strs == null || strs.length == 0)
2007 } 4845 {
2008 if (array[i] != null) { 4846 return EMPTY;
2009 buf.append(array[i]); 4847 }
2010 } 4848 int smallestIndexOfDiff = indexOfDifference(strs);
2011 } 4849 if (smallestIndexOfDiff == -1)
2012 return buf.toString(); 4850 {
2013 } 4851 // all strings were identical
2014 4852 if (strs[0] == null)
2015 // Delete 4853 {
2016 //----------------------------------------------------------------------- 4854 return EMPTY;
2017 4855 }
2018 /** 4856 return strs[0];
2019 * <p>Deletes all whitespaces from a String as defined by 4857 } else if (smallestIndexOfDiff == 0)
2020 * {@link Character#isWhitespace(char)}.</p> 4858 {
2021 * 4859 // there were no common initial characters
2022 * <pre> 4860 return EMPTY;
2023 * StringUtils.deleteWhitespace(null) = null 4861 } else
2024 * StringUtils.deleteWhitespace("") = "" 4862 {
2025 * StringUtils.deleteWhitespace("abc") = "abc" 4863 // we found a common initial character sequence
2026 * StringUtils.deleteWhitespace(" ab c ") = "abc" 4864 return strs[0].substring(0, smallestIndexOfDiff);
2027 * </pre> 4865 }
2028 * 4866 }
2029 * @param str the String to delete whitespace from, may be null 4867
2030 * @return the String without whitespaces, <code>null</code> if null String input 4868 // Misc
2031 */ 4869 //-----------------------------------------------------------------------
2032 public static String deleteWhitespace(String str) { 4870
2033 if (isEmpty(str)) { 4871 /**
2034 return str; 4872 * <p>Find the Levenshtein distance between two Strings.</p>
2035 } 4873 * <p/>
2036 int sz = str.length(); 4874 * <p>This is the number of changes needed to change one String into
2037 char[] chs = new char[sz]; 4875 * another, where each change is a single character modification (deletion,
2038 int count = 0; 4876 * insertion or substitution).</p>
2039 for (int i = 0; i < sz; i++) { 4877 * <p/>
2040 if (!Character.isWhitespace(str.charAt(i))) { 4878 * <p>The previous implementation of the Levenshtein distance algorithm
2041 chs[count++] = str.charAt(i); 4879 * was from <a href="http://www.merriampark.com/ld.htm">http://www.merriampark .com/ld.htm</a></p>
2042 } 4880 * <p/>
2043 } 4881 * <p>Chas Emerick has written an implementation in Java, which avoids an OutO fMemoryError
2044 if (count == sz) { 4882 * which can occur when my Java implementation is used with very large strings .<br>
2045 return str; 4883 * This implementation of the Levenshtein distance algorithm
2046 } 4884 * is from <a href="http://www.merriampark.com/ldjava.htm">http://www.merriamp ark.com/ldjava.htm</a></p>
2047 return new String(chs, 0, count); 4885 * <p/>
2048 } 4886 * <pre>
2049 4887 * StringUtils.getLevenshteinDistance(null, *) = IllegalArgumentEx ception
2050 // Remove 4888 * StringUtils.getLevenshteinDistance(*, null) = IllegalArgumentEx ception
2051 //----------------------------------------------------------------------- 4889 * StringUtils.getLevenshteinDistance("","") = 0
2052 /** 4890 * StringUtils.getLevenshteinDistance("","a") = 1
2053 * <p>Removes a substring only if it is at the begining of a source string, 4891 * StringUtils.getLevenshteinDistance("aaapppp", "") = 7
2054 * otherwise returns the source string.</p> 4892 * StringUtils.getLevenshteinDistance("frog", "fog") = 1
2055 * 4893 * StringUtils.getLevenshteinDistance("fly", "ant") = 3
2056 * <p>A <code>null</code> source string will return <code>null</code>. 4894 * StringUtils.getLevenshteinDistance("elephant", "hippo") = 7
2057 * An empty ("") source string will return the empty string. 4895 * StringUtils.getLevenshteinDistance("hippo", "elephant") = 7
2058 * A <code>null</code> search string will return the source string.</p> 4896 * StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
2059 * 4897 * StringUtils.getLevenshteinDistance("hello", "hallo") = 1
2060 * <pre> 4898 * </pre>
2061 * StringUtils.removeStart(null, *) = null 4899 *
2062 * StringUtils.removeStart("", *) = "" 4900 * @param s the first String, must not be null
2063 * StringUtils.removeStart(*, null) = * 4901 * @param t the second String, must not be null
2064 * StringUtils.removeStart("www.domain.com", "www.") = "domain.com" 4902 * @return result distance
2065 * StringUtils.removeStart("domain.com", "www.") = "domain.com" 4903 * @throws IllegalArgumentException if either String input <code>null</code>
2066 * StringUtils.removeStart("www.domain.com", "domain") = "www.domain.com" 4904 */
2067 * StringUtils.removeStart("abc", "") = "abc" 4905 public static int getLevenshteinDistance(String s, String t)
2068 * </pre> 4906 {
2069 * 4907 if (s == null || t == null)
2070 * @param str the source String to search, may be null 4908 {
2071 * @param remove the String to search for and remove, may be null 4909 throw new IllegalArgumentException("Strings must not be null");
2072 * @return the substring with the string removed if found, 4910 }
2073 * <code>null</code> if null String input
2074 * @since 2.1
2075 */
2076 public static String removeStart(String str, String remove) {
2077 if (isEmpty(str) || isEmpty(remove)) {
2078 return str;
2079 }
2080 if (str.startsWith(remove)){
2081 return str.substring(remove.length());
2082 }
2083 return str;
2084 }
2085
2086 /**
2087 * <p>Case insensitive removal of a substring if it is at the begining of a source string,
2088 * otherwise returns the source string.</p>
2089 *
2090 * <p>A <code>null</code> source string will return <code>null</code>.
2091 * An empty ("") source string will return the empty string.
2092 * A <code>null</code> search string will return the source string.</p>
2093 *
2094 * <pre>
2095 * StringUtils.removeStartIgnoreCase(null, *) = null
2096 * StringUtils.removeStartIgnoreCase("", *) = ""
2097 * StringUtils.removeStartIgnoreCase(*, null) = *
2098 * StringUtils.removeStartIgnoreCase("www.domain.com", "www.") = "domain.c om"
2099 * StringUtils.removeStartIgnoreCase("www.domain.com", "WWW.") = "domain.c om"
2100 * StringUtils.removeStartIgnoreCase("domain.com", "www.") = "domain.c om"
2101 * StringUtils.removeStartIgnoreCase("www.domain.com", "domain") = "www.doma in.com"
2102 * StringUtils.removeStartIgnoreCase("abc", "") = "abc"
2103 * </pre>
2104 *
2105 * @param str the source String to search, may be null
2106 * @param remove the String to search for (case insensitive) and remove, ma y be null
2107 * @return the substring with the string removed if found,
2108 * <code>null</code> if null String input
2109 * @since 2.4
2110 */
2111 public static String removeStartIgnoreCase(String str, String remove) {
2112 if (isEmpty(str) || isEmpty(remove)) {
2113 return str;
2114 }
2115 if (startsWithIgnoreCase(str, remove)) {
2116 return str.substring(remove.length());
2117 }
2118 return str;
2119 }
2120
2121 /**
2122 * <p>Removes a substring only if it is at the end of a source string,
2123 * otherwise returns the source string.</p>
2124 *
2125 * <p>A <code>null</code> source string will return <code>null</code>.
2126 * An empty ("") source string will return the empty string.
2127 * A <code>null</code> search string will return the source string.</p>
2128 *
2129 * <pre>
2130 * StringUtils.removeEnd(null, *) = null
2131 * StringUtils.removeEnd("", *) = ""
2132 * StringUtils.removeEnd(*, null) = *
2133 * StringUtils.removeEnd("www.domain.com", ".com.") = "www.domain.com"
2134 * StringUtils.removeEnd("www.domain.com", ".com") = "www.domain"
2135 * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"
2136 * StringUtils.removeEnd("abc", "") = "abc"
2137 * </pre>
2138 *
2139 * @param str the source String to search, may be null
2140 * @param remove the String to search for and remove, may be null
2141 * @return the substring with the string removed if found,
2142 * <code>null</code> if null String input
2143 * @since 2.1
2144 */
2145 public static String removeEnd(String str, String remove) {
2146 if (isEmpty(str) || isEmpty(remove)) {
2147 return str;
2148 }
2149 if (str.endsWith(remove)) {
2150 return str.substring(0, str.length() - remove.length());
2151 }
2152 return str;
2153 }
2154
2155 /**
2156 * <p>Case insensitive removal of a substring if it is at the end of a sourc e string,
2157 * otherwise returns the source string.</p>
2158 *
2159 * <p>A <code>null</code> source string will return <code>null</code>.
2160 * An empty ("") source string will return the empty string.
2161 * A <code>null</code> search string will return the source string.</p>
2162 *
2163 * <pre>
2164 * StringUtils.removeEnd(null, *) = null
2165 * StringUtils.removeEnd("", *) = ""
2166 * StringUtils.removeEnd(*, null) = *
2167 * StringUtils.removeEnd("www.domain.com", ".com.") = "www.domain.com."
2168 * StringUtils.removeEnd("www.domain.com", ".com") = "www.domain"
2169 * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"
2170 * StringUtils.removeEnd("abc", "") = "abc"
2171 * </pre>
2172 *
2173 * @param str the source String to search, may be null
2174 * @param remove the String to search for (case insensitive) and remove, ma y be null
2175 * @return the substring with the string removed if found,
2176 * <code>null</code> if null String input
2177 * @since 2.4
2178 */
2179 public static String removeEndIgnoreCase(String str, String remove) {
2180 if (isEmpty(str) || isEmpty(remove)) {
2181 return str;
2182 }
2183 if (endsWithIgnoreCase(str, remove)) {
2184 return str.substring(0, str.length() - remove.length());
2185 }
2186 return str;
2187 }
2188
2189 /**
2190 * <p>Removes all occurrences of a substring from within the source string.< /p>
2191 *
2192 * <p>A <code>null</code> source string will return <code>null</code>.
2193 * An empty ("") source string will return the empty string.
2194 * A <code>null</code> remove string will return the source string.
2195 * An empty ("") remove string will return the source string.</p>
2196 *
2197 * <pre>
2198 * StringUtils.remove(null, *) = null
2199 * StringUtils.remove("", *) = ""
2200 * StringUtils.remove(*, null) = *
2201 * StringUtils.remove(*, "") = *
2202 * StringUtils.remove("queued", "ue") = "qd"
2203 * StringUtils.remove("queued", "zz") = "queued"
2204 * </pre>
2205 *
2206 * @param str the source String to search, may be null
2207 * @param remove the String to search for and remove, may be null
2208 * @return the substring with the string removed if found,
2209 * <code>null</code> if null String input
2210 * @since 2.1
2211 */
2212 public static String remove(String str, String remove) {
2213 if (isEmpty(str) || isEmpty(remove)) {
2214 return str;
2215 }
2216 return replace(str, remove, EMPTY, -1);
2217 }
2218
2219 /**
2220 * <p>Removes all occurrences of a character from within the source string.< /p>
2221 *
2222 * <p>A <code>null</code> source string will return <code>null</code>.
2223 * An empty ("") source string will return the empty string.</p>
2224 *
2225 * <pre>
2226 * StringUtils.remove(null, *) = null
2227 * StringUtils.remove("", *) = ""
2228 * StringUtils.remove("queued", 'u') = "qeed"
2229 * StringUtils.remove("queued", 'z') = "queued"
2230 * </pre>
2231 *
2232 * @param str the source String to search, may be null
2233 * @param remove the char to search for and remove, may be null
2234 * @return the substring with the char removed if found,
2235 * <code>null</code> if null String input
2236 * @since 2.1
2237 */
2238 public static String remove(String str, char remove) {
2239 if (isEmpty(str) || str.indexOf(remove) == -1) {
2240 return str;
2241 }
2242 char[] chars = str.toCharArray();
2243 int pos = 0;
2244 for (int i = 0; i < chars.length; i++) {
2245 if (chars[i] != remove) {
2246 chars[pos++] = chars[i];
2247 }
2248 }
2249 return new String(chars, 0, pos);
2250 }
2251
2252 // Replacing
2253 //-----------------------------------------------------------------------
2254 /**
2255 * <p>Replaces a String with another String inside a larger String, once.</p >
2256 *
2257 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
2258 *
2259 * <pre>
2260 * StringUtils.replaceOnce(null, *, *) = null
2261 * StringUtils.replaceOnce("", *, *) = ""
2262 * StringUtils.replaceOnce("any", null, *) = "any"
2263 * StringUtils.replaceOnce("any", *, null) = "any"
2264 * StringUtils.replaceOnce("any", "", *) = "any"
2265 * StringUtils.replaceOnce("aba", "a", null) = "aba"
2266 * StringUtils.replaceOnce("aba", "a", "") = "ba"
2267 * StringUtils.replaceOnce("aba", "a", "z") = "zba"
2268 * </pre>
2269 *
2270 * @see #replace(String text, String searchString, String replacement, int m ax)
2271 * @param text text to search and replace in, may be null
2272 * @param searchString the String to search for, may be null
2273 * @param replacement the String to replace with, may be null
2274 * @return the text with any replacements processed,
2275 * <code>null</code> if null String input
2276 */
2277 public static String replaceOnce(String text, String searchString, String re placement) {
2278 return replace(text, searchString, replacement, 1);
2279 }
2280
2281 /**
2282 * <p>Replaces all occurrences of a String within another String.</p>
2283 *
2284 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
2285 *
2286 * <pre>
2287 * StringUtils.replace(null, *, *) = null
2288 * StringUtils.replace("", *, *) = ""
2289 * StringUtils.replace("any", null, *) = "any"
2290 * StringUtils.replace("any", *, null) = "any"
2291 * StringUtils.replace("any", "", *) = "any"
2292 * StringUtils.replace("aba", "a", null) = "aba"
2293 * StringUtils.replace("aba", "a", "") = "b"
2294 * StringUtils.replace("aba", "a", "z") = "zbz"
2295 * </pre>
2296 *
2297 * @see #replace(String text, String searchString, String replacement, int m ax)
2298 * @param text text to search and replace in, may be null
2299 * @param searchString the String to search for, may be null
2300 * @param replacement the String to replace it with, may be null
2301 * @return the text with any replacements processed,
2302 * <code>null</code> if null String input
2303 */
2304 public static String replace(String text, String searchString, String replac ement) {
2305 return replace(text, searchString, replacement, -1);
2306 }
2307
2308 /**
2309 * <p>Replaces a String with another String inside a larger String,
2310 * for the first <code>max</code> values of the search String.</p>
2311 *
2312 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
2313 *
2314 * <pre>
2315 * StringUtils.replace(null, *, *, *) = null
2316 * StringUtils.replace("", *, *, *) = ""
2317 * StringUtils.replace("any", null, *, *) = "any"
2318 * StringUtils.replace("any", *, null, *) = "any"
2319 * StringUtils.replace("any", "", *, *) = "any"
2320 * StringUtils.replace("any", *, *, 0) = "any"
2321 * StringUtils.replace("abaa", "a", null, -1) = "abaa"
2322 * StringUtils.replace("abaa", "a", "", -1) = "b"
2323 * StringUtils.replace("abaa", "a", "z", 0) = "abaa"
2324 * StringUtils.replace("abaa", "a", "z", 1) = "zbaa"
2325 * StringUtils.replace("abaa", "a", "z", 2) = "zbza"
2326 * StringUtils.replace("abaa", "a", "z", -1) = "zbzz"
2327 * </pre>
2328 *
2329 * @param text text to search and replace in, may be null
2330 * @param searchString the String to search for, may be null
2331 * @param replacement the String to replace it with, may be null
2332 * @param max maximum number of values to replace, or <code>-1</code> if no maximum
2333 * @return the text with any replacements processed,
2334 * <code>null</code> if null String input
2335 */
2336 public static String replace(String text, String searchString, String replac ement, int max) {
2337 if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
2338 return text;
2339 }
2340 int start = 0;
2341 int end = text.indexOf(searchString, start);
2342 if (end == -1) {
2343 return text;
2344 }
2345 int replLength = searchString.length();
2346 int increase = replacement.length() - replLength;
2347 increase = (increase < 0 ? 0 : increase);
2348 increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
2349 StringBuffer buf = new StringBuffer(text.length() + increase);
2350 while (end != -1) {
2351 buf.append(text.substring(start, end)).append(replacement);
2352 start = end + replLength;
2353 if (--max == 0) {
2354 break;
2355 }
2356 end = text.indexOf(searchString, start);
2357 }
2358 buf.append(text.substring(start));
2359 return buf.toString();
2360 }
2361
2362 /**
2363 * <p>
2364 * Replaces all occurrences of Strings within another String.
2365 * </p>
2366 *
2367 * <p>
2368 * A <code>null</code> reference passed to this method is a no-op, or if
2369 * any "search string" or "string to replace" is null, that replace will be
2370 * ignored. This will not repeat. For repeating replaces, call the
2371 * overloaded method.
2372 * </p>
2373 *
2374 * <pre>
2375 * StringUtils.replaceEach(null, *, *) = null
2376 * StringUtils.replaceEach("", *, *) = ""
2377 * StringUtils.replaceEach("aba", null, null) = "aba"
2378 * StringUtils.replaceEach("aba", new String[0], null) = "aba"
2379 * StringUtils.replaceEach("aba", null, new String[0]) = "aba"
2380 * StringUtils.replaceEach("aba", new String[]{"a"}, null) = "aba"
2381 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}) = " b"
2382 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}) = "aba"
2383 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{" w", "t"}) = "wcte"
2384 * (example of how it does not repeat)
2385 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{" d", "t"}) = "dcte"
2386 * </pre>
2387 *
2388 * @param text
2389 * text to search and replace in, no-op if null
2390 * @param searchList
2391 * the Strings to search for, no-op if null
2392 * @param replacementList
2393 * the Strings to replace them with, no-op if null
2394 * @return the text with any replacements processed, <code>null</code> if
2395 * null String input
2396 * @throws IndexOutOfBoundsException
2397 * if the lengths of the arrays are not the same (null is ok,
2398 * and/or size 0)
2399 * @since 2.4
2400 */
2401 public static String replaceEach(String text, String[] searchList, String[] replacementList) {
2402 return replaceEach(text, searchList, replacementList, false, 0);
2403 }
2404
2405 /**
2406 * <p>
2407 * Replaces all occurrences of Strings within another String.
2408 * </p>
2409 *
2410 * <p>
2411 * A <code>null</code> reference passed to this method is a no-op, or if
2412 * any "search string" or "string to replace" is null, that replace will be
2413 * ignored. This will not repeat. For repeating replaces, call the
2414 * overloaded method.
2415 * </p>
2416 *
2417 * <pre>
2418 * StringUtils.replaceEach(null, *, *, *) = null
2419 * StringUtils.replaceEach("", *, *, *) = ""
2420 * StringUtils.replaceEach("aba", null, null, *) = "aba"
2421 * StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
2422 * StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
2423 * StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
2424 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
2425 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
2426 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{" w", "t"}, *) = "wcte"
2427 * (example of how it repeats)
2428 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{" d", "t"}, false) = "dcte"
2429 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{" d", "t"}, true) = "tcte"
2430 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{" d", "ab"}, true) = IllegalArgumentException
2431 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{" d", "ab"}, false) = "dcabe"
2432 * </pre>
2433 *
2434 * @param text
2435 * text to search and replace in, no-op if null
2436 * @param searchList
2437 * the Strings to search for, no-op if null
2438 * @param replacementList
2439 * the Strings to replace them with, no-op if null
2440 * @return the text with any replacements processed, <code>null</code> if
2441 * null String input
2442 * @throws IllegalArgumentException
2443 * if the search is repeating and there is an endless loop due
2444 * to outputs of one being inputs to another
2445 * @throws IndexOutOfBoundsException
2446 * if the lengths of the arrays are not the same (null is ok,
2447 * and/or size 0)
2448 * @since 2.4
2449 */
2450 public static String replaceEachRepeatedly(String text, String[] searchList, String[] replacementList) {
2451 // timeToLive should be 0 if not used or nothing to replace, else it's
2452 // the length of the replace array
2453 int timeToLive = searchList == null ? 0 : searchList.length;
2454 return replaceEach(text, searchList, replacementList, true, timeToLive);
2455 }
2456
2457 /**
2458 * <p>
2459 * Replaces all occurrences of Strings within another String.
2460 * </p>
2461 *
2462 * <p>
2463 * A <code>null</code> reference passed to this method is a no-op, or if
2464 * any "search string" or "string to replace" is null, that replace will be
2465 * ignored.
2466 * </p>
2467 *
2468 * <pre>
2469 * StringUtils.replaceEach(null, *, *, *) = null
2470 * StringUtils.replaceEach("", *, *, *) = ""
2471 * StringUtils.replaceEach("aba", null, null, *) = "aba"
2472 * StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
2473 * StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
2474 * StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
2475 * StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
2476 * StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
2477 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{" w", "t"}, *) = "wcte"
2478 * (example of how it repeats)
2479 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{" d", "t"}, false) = "dcte"
2480 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{" d", "t"}, true) = "tcte"
2481 * StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{" d", "ab"}, *) = IllegalArgumentException
2482 * </pre>
2483 *
2484 * @param text
2485 * text to search and replace in, no-op if null
2486 * @param searchList
2487 * the Strings to search for, no-op if null
2488 * @param replacementList
2489 * the Strings to replace them with, no-op if null
2490 * @param repeat if true, then replace repeatedly
2491 * until there are no more possible replacements or timeToLive < 0
2492 * @param timeToLive
2493 * if less than 0 then there is a circular reference and endless
2494 * loop
2495 * @return the text with any replacements processed, <code>null</code> if
2496 * null String input
2497 * @throws IllegalArgumentException
2498 * if the search is repeating and there is an endless loop due
2499 * to outputs of one being inputs to another
2500 * @throws IndexOutOfBoundsException
2501 * if the lengths of the arrays are not the same (null is ok,
2502 * and/or size 0)
2503 * @since 2.4
2504 */
2505 private static String replaceEach(String text, String[] searchList, String[] replacementList,
2506 boolean repeat, int timeToLive)
2507 {
2508
2509 // mchyzer Performance note: This creates very few new objects (one majo r goal)
2510 // let me know if there are performance requests, we can create a harnes s to measure
2511
2512 if (text == null || text.length() == 0 || searchList == null ||
2513 searchList.length == 0 || replacementList == null || replacementList .length == 0)
2514 {
2515 return text;
2516 }
2517
2518 // if recursing, this shouldnt be less than 0
2519 if (timeToLive < 0) {
2520 throw new IllegalStateException("TimeToLive of " + timeToLive + " is less than 0: " + text);
2521 }
2522
2523 int searchLength = searchList.length;
2524 int replacementLength = replacementList.length;
2525
2526 // make sure lengths are ok, these need to be equal
2527 if (searchLength != replacementLength) {
2528 throw new IllegalArgumentException("Search and Replace array lengths don't match: "
2529 + searchLength
2530 + " vs "
2531 + replacementLength);
2532 }
2533
2534 // keep track of which still have matches
2535 boolean[] noMoreMatchesForReplIndex = new boolean[searchLength];
2536
2537 // index on index that the match was found
2538 int textIndex = -1;
2539 int replaceIndex = -1;
2540 int tempIndex = -1;
2541
2542 // index of replace array that will replace the search string found
2543 // NOTE: logic duplicated below START
2544 for (int i = 0; i < searchLength; i++) {
2545 if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
2546 searchList[i].length() == 0 || replacementList[i] == null)
2547 {
2548 continue;
2549 }
2550 tempIndex = text.indexOf(searchList[i]);
2551
2552 // see if we need to keep searching for this
2553 if (tempIndex == -1) {
2554 noMoreMatchesForReplIndex[i] = true;
2555 } else {
2556 if (textIndex == -1 || tempIndex < textIndex) {
2557 textIndex = tempIndex;
2558 replaceIndex = i;
2559 }
2560 }
2561 }
2562 // NOTE: logic mostly below END
2563
2564 // no search strings found, we are done
2565 if (textIndex == -1) {
2566 return text;
2567 }
2568
2569 int start = 0;
2570
2571 // get a good guess on the size of the result buffer so it doesnt have t o double if it goes over a bit
2572 int increase = 0;
2573
2574 // count the replacement text elements that are larger than their corres ponding text being replaced
2575 for (int i = 0; i < searchList.length; i++) {
2576 int greater = replacementList[i].length() - searchList[i].length();
2577 if (greater > 0) {
2578 increase += 3 * greater; // assume 3 matches
2579 }
2580 }
2581 // have upper-bound at 20% increase, then let Java take over
2582 increase = Math.min(increase, text.length() / 5);
2583
2584 StringBuffer buf = new StringBuffer(text.length() + increase);
2585
2586 while (textIndex != -1) {
2587
2588 for (int i = start; i < textIndex; i++) {
2589 buf.append(text.charAt(i));
2590 }
2591 buf.append(replacementList[replaceIndex]);
2592
2593 start = textIndex + searchList[replaceIndex].length();
2594
2595 textIndex = -1;
2596 replaceIndex = -1;
2597 tempIndex = -1;
2598 // find the next earliest match
2599 // NOTE: logic mostly duplicated above START
2600 for (int i = 0; i < searchLength; i++) {
2601 if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
2602 searchList[i].length() == 0 || replacementList[i] == null)
2603 {
2604 continue;
2605 }
2606 tempIndex = text.indexOf(searchList[i], start);
2607
2608 // see if we need to keep searching for this
2609 if (tempIndex == -1) {
2610 noMoreMatchesForReplIndex[i] = true;
2611 } else {
2612 if (textIndex == -1 || tempIndex < textIndex) {
2613 textIndex = tempIndex;
2614 replaceIndex = i;
2615 }
2616 }
2617 }
2618 // NOTE: logic duplicated above END
2619
2620 }
2621 int textLength = text.length();
2622 for (int i = start; i < textLength; i++) {
2623 buf.append(text.charAt(i));
2624 }
2625 String result = buf.toString();
2626 if (!repeat) {
2627 return result;
2628 }
2629
2630 return replaceEach(result, searchList, replacementList, repeat, timeToLi ve - 1);
2631 }
2632
2633 // Replace, character based
2634 //-----------------------------------------------------------------------
2635 /**
2636 * <p>Replaces all occurrences of a character in a String with another.
2637 * This is a null-safe version of {@link String#replace(char, char)}.</p>
2638 *
2639 * <p>A <code>null</code> string input returns <code>null</code>.
2640 * An empty ("") string input returns an empty string.</p>
2641 *
2642 * <pre>
2643 * StringUtils.replaceChars(null, *, *) = null
2644 * StringUtils.replaceChars("", *, *) = ""
2645 * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya"
2646 * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba"
2647 * </pre>
2648 *
2649 * @param str String to replace characters in, may be null
2650 * @param searchChar the character to search for, may be null
2651 * @param replaceChar the character to replace, may be null
2652 * @return modified String, <code>null</code> if null string input
2653 * @since 2.0
2654 */
2655 public static String replaceChars(String str, char searchChar, char replaceC har) {
2656 if (str == null) {
2657 return null;
2658 }
2659 return str.replace(searchChar, replaceChar);
2660 }
2661
2662 /**
2663 * <p>Replaces multiple characters in a String in one go.
2664 * This method can also be used to delete characters.</p>
2665 *
2666 * <p>For example:<br />
2667 * <code>replaceChars(&quot;hello&quot;, &quot;ho&quot;, &quot;jy&quot;) = j elly</code>.</p>
2668 *
2669 * <p>A <code>null</code> string input returns <code>null</code>.
2670 * An empty ("") string input returns an empty string.
2671 * A null or empty set of search characters returns the input string.</p>
2672 *
2673 * <p>The length of the search characters should normally equal the length
2674 * of the replace characters.
2675 * If the search characters is longer, then the extra search characters
2676 * are deleted.
2677 * If the search characters is shorter, then the extra replace characters
2678 * are ignored.</p>
2679 *
2680 * <pre>
2681 * StringUtils.replaceChars(null, *, *) = null
2682 * StringUtils.replaceChars("", *, *) = ""
2683 * StringUtils.replaceChars("abc", null, *) = "abc"
2684 * StringUtils.replaceChars("abc", "", *) = "abc"
2685 * StringUtils.replaceChars("abc", "b", null) = "ac"
2686 * StringUtils.replaceChars("abc", "b", "") = "ac"
2687 * StringUtils.replaceChars("abcba", "bc", "yz") = "ayzya"
2688 * StringUtils.replaceChars("abcba", "bc", "y") = "ayya"
2689 * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya"
2690 * </pre>
2691 *
2692 * @param str String to replace characters in, may be null
2693 * @param searchChars a set of characters to search for, may be null
2694 * @param replaceChars a set of characters to replace, may be null
2695 * @return modified String, <code>null</code> if null string input
2696 * @since 2.0
2697 */
2698 public static String replaceChars(String str, String searchChars, String rep laceChars) {
2699 if (isEmpty(str) || isEmpty(searchChars)) {
2700 return str;
2701 }
2702 if (replaceChars == null) {
2703 replaceChars = EMPTY;
2704 }
2705 boolean modified = false;
2706 int replaceCharsLength = replaceChars.length();
2707 int strLength = str.length();
2708 StringBuffer buf = new StringBuffer(strLength);
2709 for (int i = 0; i < strLength; i++) {
2710 char ch = str.charAt(i);
2711 int index = searchChars.indexOf(ch);
2712 if (index >= 0) {
2713 modified = true;
2714 if (index < replaceCharsLength) {
2715 buf.append(replaceChars.charAt(index));
2716 }
2717 } else {
2718 buf.append(ch);
2719 }
2720 }
2721 if (modified) {
2722 return buf.toString();
2723 }
2724 return str;
2725 }
2726
2727 // Overlay
2728 //-----------------------------------------------------------------------
2729 /**
2730 * <p>Overlays part of a String with another String.</p>
2731 *
2732 * <pre>
2733 * StringUtils.overlayString(null, *, *, *) = NullPointerException
2734 * StringUtils.overlayString(*, null, *, *) = NullPointerException
2735 * StringUtils.overlayString("", "abc", 0, 0) = "abc"
2736 * StringUtils.overlayString("abcdef", null, 2, 4) = "abef"
2737 * StringUtils.overlayString("abcdef", "", 2, 4) = "abef"
2738 * StringUtils.overlayString("abcdef", "zzzz", 2, 4) = "abzzzzef"
2739 * StringUtils.overlayString("abcdef", "zzzz", 4, 2) = "abcdzzzzcdef"
2740 * StringUtils.overlayString("abcdef", "zzzz", -1, 4) = IndexOutOfBoundsExce ption
2741 * StringUtils.overlayString("abcdef", "zzzz", 2, 8) = IndexOutOfBoundsExce ption
2742 * </pre>
2743 *
2744 * @param text the String to do overlaying in, may be null
2745 * @param overlay the String to overlay, may be null
2746 * @param start the position to start overlaying at, must be valid
2747 * @param end the position to stop overlaying before, must be valid
2748 * @return overlayed String, <code>null</code> if null String input
2749 * @throws NullPointerException if text or overlay is null
2750 * @throws IndexOutOfBoundsException if either position is invalid
2751 * @deprecated Use better named {@link #overlay(String, String, int, int)} i nstead.
2752 * Method will be removed in Commons Lang 3.0.
2753 */
2754 public static String overlayString(String text, String overlay, int start, i nt end) {
2755 return new StringBuffer(start + overlay.length() + text.length() - end + 1)
2756 .append(text.substring(0, start))
2757 .append(overlay)
2758 .append(text.substring(end))
2759 .toString();
2760 }
2761
2762 /**
2763 * <p>Overlays part of a String with another String.</p>
2764 *
2765 * <p>A <code>null</code> string input returns <code>null</code>.
2766 * A negative index is treated as zero.
2767 * An index greater than the string length is treated as the string length.
2768 * The start index is always the smaller of the two indices.</p>
2769 *
2770 * <pre>
2771 * StringUtils.overlay(null, *, *, *) = null
2772 * StringUtils.overlay("", "abc", 0, 0) = "abc"
2773 * StringUtils.overlay("abcdef", null, 2, 4) = "abef"
2774 * StringUtils.overlay("abcdef", "", 2, 4) = "abef"
2775 * StringUtils.overlay("abcdef", "", 4, 2) = "abef"
2776 * StringUtils.overlay("abcdef", "zzzz", 2, 4) = "abzzzzef"
2777 * StringUtils.overlay("abcdef", "zzzz", 4, 2) = "abzzzzef"
2778 * StringUtils.overlay("abcdef", "zzzz", -1, 4) = "zzzzef"
2779 * StringUtils.overlay("abcdef", "zzzz", 2, 8) = "abzzzz"
2780 * StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
2781 * StringUtils.overlay("abcdef", "zzzz", 8, 10) = "abcdefzzzz"
2782 * </pre>
2783 *
2784 * @param str the String to do overlaying in, may be null
2785 * @param overlay the String to overlay, may be null
2786 * @param start the position to start overlaying at
2787 * @param end the position to stop overlaying before
2788 * @return overlayed String, <code>null</code> if null String input
2789 * @since 2.0
2790 */
2791 public static String overlay(String str, String overlay, int start, int end) {
2792 if (str == null) {
2793 return null;
2794 }
2795 if (overlay == null) {
2796 overlay = EMPTY;
2797 }
2798 int len = str.length();
2799 if (start < 0) {
2800 start = 0;
2801 }
2802 if (start > len) {
2803 start = len;
2804 }
2805 if (end < 0) {
2806 end = 0;
2807 }
2808 if (end > len) {
2809 end = len;
2810 }
2811 if (start > end) {
2812 int temp = start;
2813 start = end;
2814 end = temp;
2815 }
2816 return new StringBuffer(len + start - end + overlay.length() + 1)
2817 .append(str.substring(0, start))
2818 .append(overlay)
2819 .append(str.substring(end))
2820 .toString();
2821 }
2822
2823 // Chomping
2824 //-----------------------------------------------------------------------
2825 /**
2826 * <p>Removes one newline from end of a String if it's there,
2827 * otherwise leave it alone. A newline is &quot;<code>\n</code>&quot;,
2828 * &quot;<code>\r</code>&quot;, or &quot;<code>\r\n</code>&quot;.</p>
2829 *
2830 * <p>NOTE: This method changed in 2.0.
2831 * It now more closely matches Perl chomp.</p>
2832 *
2833 * <pre>
2834 * StringUtils.chomp(null) = null
2835 * StringUtils.chomp("") = ""
2836 * StringUtils.chomp("abc \r") = "abc "
2837 * StringUtils.chomp("abc\n") = "abc"
2838 * StringUtils.chomp("abc\r\n") = "abc"
2839 * StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
2840 * StringUtils.chomp("abc\n\r") = "abc\n"
2841 * StringUtils.chomp("abc\n\rabc") = "abc\n\rabc"
2842 * StringUtils.chomp("\r") = ""
2843 * StringUtils.chomp("\n") = ""
2844 * StringUtils.chomp("\r\n") = ""
2845 * </pre>
2846 *
2847 * @param str the String to chomp a newline from, may be null
2848 * @return String without newline, <code>null</code> if null String input
2849 */
2850 public static String chomp(String str) {
2851 if (isEmpty(str)) {
2852 return str;
2853 }
2854
2855 if (str.length() == 1) {
2856 char ch = str.charAt(0);
2857 if (ch == CharUtils.CR || ch == CharUtils.LF) {
2858 return EMPTY;
2859 }
2860 return str;
2861 }
2862
2863 int lastIdx = str.length() - 1;
2864 char last = str.charAt(lastIdx);
2865
2866 if (last == CharUtils.LF) {
2867 if (str.charAt(lastIdx - 1) == CharUtils.CR) {
2868 lastIdx--;
2869 }
2870 } else if (last != CharUtils.CR) {
2871 lastIdx++;
2872 }
2873 return str.substring(0, lastIdx);
2874 }
2875
2876 /**
2877 * <p>Removes <code>separator</code> from the end of
2878 * <code>str</code> if it's there, otherwise leave it alone.</p>
2879 *
2880 * <p>NOTE: This method changed in version 2.0.
2881 * It now more closely matches Perl chomp.
2882 * For the previous behavior, use {@link #substringBeforeLast(String, String )}.
2883 * This method uses {@link String#endsWith(String)}.</p>
2884 *
2885 * <pre>
2886 * StringUtils.chomp(null, *) = null
2887 * StringUtils.chomp("", *) = ""
2888 * StringUtils.chomp("foobar", "bar") = "foo"
2889 * StringUtils.chomp("foobar", "baz") = "foobar"
2890 * StringUtils.chomp("foo", "foo") = ""
2891 * StringUtils.chomp("foo ", "foo") = "foo "
2892 * StringUtils.chomp(" foo", "foo") = " "
2893 * StringUtils.chomp("foo", "foooo") = "foo"
2894 * StringUtils.chomp("foo", "") = "foo"
2895 * StringUtils.chomp("foo", null) = "foo"
2896 * </pre>
2897 *
2898 * @param str the String to chomp from, may be null
2899 * @param separator separator String, may be null
2900 * @return String without trailing separator, <code>null</code> if null Stri ng input
2901 */
2902 public static String chomp(String str, String separator) {
2903 if (isEmpty(str) || separator == null) {
2904 return str;
2905 }
2906 if (str.endsWith(separator)) {
2907 return str.substring(0, str.length() - separator.length());
2908 }
2909 return str;
2910 }
2911
2912 /**
2913 * <p>Remove any &quot;\n&quot; if and only if it is at the end
2914 * of the supplied String.</p>
2915 *
2916 * @param str the String to chomp from, must not be null
2917 * @return String without chomped ending
2918 * @throws NullPointerException if str is <code>null</code>
2919 * @deprecated Use {@link #chomp(String)} instead.
2920 * Method will be removed in Commons Lang 3.0.
2921 */
2922 public static String chompLast(String str) {
2923 return chompLast(str, "\n");
2924 }
2925
2926 /**
2927 * <p>Remove a value if and only if the String ends with that value.</p>
2928 *
2929 * @param str the String to chomp from, must not be null
2930 * @param sep the String to chomp, must not be null
2931 * @return String without chomped ending
2932 * @throws NullPointerException if str or sep is <code>null</code>
2933 * @deprecated Use {@link #chomp(String,String)} instead.
2934 * Method will be removed in Commons Lang 3.0.
2935 */
2936 public static String chompLast(String str, String sep) {
2937 if (str.length() == 0) {
2938 return str;
2939 }
2940 String sub = str.substring(str.length() - sep.length());
2941 if (sep.equals(sub)) {
2942 return str.substring(0, str.length() - sep.length());
2943 }
2944 return str;
2945 }
2946
2947 /**
2948 * <p>Remove everything and return the last value of a supplied String, and
2949 * everything after it from a String.</p>
2950 *
2951 * @param str the String to chomp from, must not be null
2952 * @param sep the String to chomp, must not be null
2953 * @return String chomped
2954 * @throws NullPointerException if str or sep is <code>null</code>
2955 * @deprecated Use {@link #substringAfterLast(String, String)} instead
2956 * (although this doesn't include the separator)
2957 * Method will be removed in Commons Lang 3.0.
2958 */
2959 public static String getChomp(String str, String sep) {
2960 int idx = str.lastIndexOf(sep);
2961 if (idx == str.length() - sep.length()) {
2962 return sep;
2963 } else if (idx != -1) {
2964 return str.substring(idx);
2965 } else {
2966 return EMPTY;
2967 }
2968 }
2969
2970 /**
2971 * <p>Remove the first value of a supplied String, and everything before it
2972 * from a String.</p>
2973 *
2974 * @param str the String to chomp from, must not be null
2975 * @param sep the String to chomp, must not be null
2976 * @return String without chomped beginning
2977 * @throws NullPointerException if str or sep is <code>null</code>
2978 * @deprecated Use {@link #substringAfter(String,String)} instead.
2979 * Method will be removed in Commons Lang 3.0.
2980 */
2981 public static String prechomp(String str, String sep) {
2982 int idx = str.indexOf(sep);
2983 if (idx == -1) {
2984 return str;
2985 }
2986 return str.substring(idx + sep.length());
2987 }
2988
2989 /**
2990 * <p>Remove and return everything before the first value of a
2991 * supplied String from another String.</p>
2992 *
2993 * @param str the String to chomp from, must not be null
2994 * @param sep the String to chomp, must not be null
2995 * @return String prechomped
2996 * @throws NullPointerException if str or sep is <code>null</code>
2997 * @deprecated Use {@link #substringBefore(String,String)} instead
2998 * (although this doesn't include the separator).
2999 * Method will be removed in Commons Lang 3.0.
3000 */
3001 public static String getPrechomp(String str, String sep) {
3002 int idx = str.indexOf(sep);
3003 if (idx == -1) {
3004 return EMPTY;
3005 }
3006 return str.substring(0, idx + sep.length());
3007 }
3008
3009 // Chopping
3010 //-----------------------------------------------------------------------
3011 /**
3012 * <p>Remove the last character from a String.</p>
3013 *
3014 * <p>If the String ends in <code>\r\n</code>, then remove both
3015 * of them.</p>
3016 *
3017 * <pre>
3018 * StringUtils.chop(null) = null
3019 * StringUtils.chop("") = ""
3020 * StringUtils.chop("abc \r") = "abc "
3021 * StringUtils.chop("abc\n") = "abc"
3022 * StringUtils.chop("abc\r\n") = "abc"
3023 * StringUtils.chop("abc") = "ab"
3024 * StringUtils.chop("abc\nabc") = "abc\nab"
3025 * StringUtils.chop("a") = ""
3026 * StringUtils.chop("\r") = ""
3027 * StringUtils.chop("\n") = ""
3028 * StringUtils.chop("\r\n") = ""
3029 * </pre>
3030 *
3031 * @param str the String to chop last character from, may be null
3032 * @return String without last character, <code>null</code> if null String i nput
3033 */
3034 public static String chop(String str) {
3035 if (str == null) {
3036 return null;
3037 }
3038 int strLen = str.length();
3039 if (strLen < 2) {
3040 return EMPTY;
3041 }
3042 int lastIdx = strLen - 1;
3043 String ret = str.substring(0, lastIdx);
3044 char last = str.charAt(lastIdx);
3045 if (last == CharUtils.LF) {
3046 if (ret.charAt(lastIdx - 1) == CharUtils.CR) {
3047 return ret.substring(0, lastIdx - 1);
3048 }
3049 }
3050 return ret;
3051 }
3052
3053 /**
3054 * <p>Removes <code>\n</code> from end of a String if it's there.
3055 * If a <code>\r</code> precedes it, then remove that too.</p>
3056 *
3057 * @param str the String to chop a newline from, must not be null
3058 * @return String without newline
3059 * @throws NullPointerException if str is <code>null</code>
3060 * @deprecated Use {@link #chomp(String)} instead.
3061 * Method will be removed in Commons Lang 3.0.
3062 */
3063 public static String chopNewline(String str) {
3064 int lastIdx = str.length() - 1;
3065 if (lastIdx <= 0) {
3066 return EMPTY;
3067 }
3068 char last = str.charAt(lastIdx);
3069 if (last == CharUtils.LF) {
3070 if (str.charAt(lastIdx - 1) == CharUtils.CR) {
3071 lastIdx--;
3072 }
3073 } else {
3074 lastIdx++;
3075 }
3076 return str.substring(0, lastIdx);
3077 }
3078
3079 // Conversion
3080 //-----------------------------------------------------------------------
3081 /**
3082 * <p>Escapes any values it finds into their String form.</p>
3083 *
3084 * <p>So a tab becomes the characters <code>'\\'</code> and
3085 * <code>'t'</code>.</p>
3086 *
3087 * <p>As of Lang 2.0, this calls {@link StringEscapeUtils#escapeJava(String) }
3088 * behind the scenes.
3089 * </p>
3090 * @see StringEscapeUtils#escapeJava(java.lang.String)
3091 * @param str String to escape values in
3092 * @return String with escaped values
3093 * @throws NullPointerException if str is <code>null</code>
3094 * @deprecated Use {@link StringEscapeUtils#escapeJava(String)}
3095 * This method will be removed in Commons Lang 3.0
3096 */
3097 public static String escape(String str) {
3098 return StringEscapeUtils.escapeJava(str);
3099 }
3100
3101 // Padding
3102 //-----------------------------------------------------------------------
3103 /**
3104 * <p>Repeat a String <code>repeat</code> times to form a
3105 * new String.</p>
3106 *
3107 * <pre>
3108 * StringUtils.repeat(null, 2) = null
3109 * StringUtils.repeat("", 0) = ""
3110 * StringUtils.repeat("", 2) = ""
3111 * StringUtils.repeat("a", 3) = "aaa"
3112 * StringUtils.repeat("ab", 2) = "abab"
3113 * StringUtils.repeat("a", -2) = ""
3114 * </pre>
3115 *
3116 * @param str the String to repeat, may be null
3117 * @param repeat number of times to repeat str, negative treated as zero
3118 * @return a new String consisting of the original String repeated,
3119 * <code>null</code> if null String input
3120 */
3121 public static String repeat(String str, int repeat) {
3122 // Performance tuned for 2.0 (JDK1.4)
3123
3124 if (str == null) {
3125 return null;
3126 }
3127 if (repeat <= 0) {
3128 return EMPTY;
3129 }
3130 int inputLength = str.length();
3131 if (repeat == 1 || inputLength == 0) {
3132 return str;
3133 }
3134 if (inputLength == 1 && repeat <= PAD_LIMIT) {
3135 return padding(repeat, str.charAt(0));
3136 }
3137
3138 int outputLength = inputLength * repeat;
3139 switch (inputLength) {
3140 case 1 :
3141 char ch = str.charAt(0);
3142 char[] output1 = new char[outputLength];
3143 for (int i = repeat - 1; i >= 0; i--) {
3144 output1[i] = ch;
3145 }
3146 return new String(output1);
3147 case 2 :
3148 char ch0 = str.charAt(0);
3149 char ch1 = str.charAt(1);
3150 char[] output2 = new char[outputLength];
3151 for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
3152 output2[i] = ch0;
3153 output2[i + 1] = ch1;
3154 }
3155 return new String(output2);
3156 default :
3157 StringBuffer buf = new StringBuffer(outputLength);
3158 for (int i = 0; i < repeat; i++) {
3159 buf.append(str);
3160 }
3161 return buf.toString();
3162 }
3163 }
3164
3165 /**
3166 * <p>Returns padding using the specified delimiter repeated
3167 * to a given length.</p>
3168 *
3169 * <pre>
3170 * StringUtils.padding(0, 'e') = ""
3171 * StringUtils.padding(3, 'e') = "eee"
3172 * StringUtils.padding(-2, 'e') = IndexOutOfBoundsException
3173 * </pre>
3174 *
3175 * <p>Note: this method doesn't not support padding with
3176 * <a href="http://www.unicode.org/glossary/#supplementary_character">Unicod e Supplementary Characters</a>
3177 * as they require a pair of <code>char</code>s to be represented.
3178 * If you are needing to support full I18N of your applications
3179 * consider using {@link #repeat(String, int)} instead.
3180 * </p>
3181 *
3182 * @param repeat number of times to repeat delim
3183 * @param padChar character to repeat
3184 * @return String with repeated character
3185 * @throws IndexOutOfBoundsException if <code>repeat &lt; 0</code>
3186 * @see #repeat(String, int)
3187 */
3188 private static String padding(int repeat, char padChar) throws IndexOutOfBou ndsException {
3189 if (repeat < 0) {
3190 throw new IndexOutOfBoundsException("Cannot pad a negative amount: " + repeat);
3191 }
3192 final char[] buf = new char[repeat];
3193 for (int i = 0; i < buf.length; i++) {
3194 buf[i] = padChar;
3195 }
3196 return new String(buf);
3197 }
3198
3199 /**
3200 * <p>Right pad a String with spaces (' ').</p>
3201 *
3202 * <p>The String is padded to the size of <code>size</code>.</p>
3203 *
3204 * <pre>
3205 * StringUtils.rightPad(null, *) = null
3206 * StringUtils.rightPad("", 3) = " "
3207 * StringUtils.rightPad("bat", 3) = "bat"
3208 * StringUtils.rightPad("bat", 5) = "bat "
3209 * StringUtils.rightPad("bat", 1) = "bat"
3210 * StringUtils.rightPad("bat", -1) = "bat"
3211 * </pre>
3212 *
3213 * @param str the String to pad out, may be null
3214 * @param size the size to pad to
3215 * @return right padded String or original String if no padding is necessary ,
3216 * <code>null</code> if null String input
3217 */
3218 public static String rightPad(String str, int size) {
3219 return rightPad(str, size, ' ');
3220 }
3221
3222 /**
3223 * <p>Right pad a String with a specified character.</p>
3224 *
3225 * <p>The String is padded to the size of <code>size</code>.</p>
3226 *
3227 * <pre>
3228 * StringUtils.rightPad(null, *, *) = null
3229 * StringUtils.rightPad("", 3, 'z') = "zzz"
3230 * StringUtils.rightPad("bat", 3, 'z') = "bat"
3231 * StringUtils.rightPad("bat", 5, 'z') = "batzz"
3232 * StringUtils.rightPad("bat", 1, 'z') = "bat"
3233 * StringUtils.rightPad("bat", -1, 'z') = "bat"
3234 * </pre>
3235 *
3236 * @param str the String to pad out, may be null
3237 * @param size the size to pad to
3238 * @param padChar the character to pad with
3239 * @return right padded String or original String if no padding is necessary ,
3240 * <code>null</code> if null String input
3241 * @since 2.0
3242 */
3243 public static String rightPad(String str, int size, char padChar) {
3244 if (str == null) {
3245 return null;
3246 }
3247 int pads = size - str.length();
3248 if (pads <= 0) {
3249 return str; // returns original String when possible
3250 }
3251 if (pads > PAD_LIMIT) {
3252 return rightPad(str, size, String.valueOf(padChar));
3253 }
3254 return str.concat(padding(pads, padChar));
3255 }
3256
3257 /**
3258 * <p>Right pad a String with a specified String.</p>
3259 *
3260 * <p>The String is padded to the size of <code>size</code>.</p>
3261 *
3262 * <pre>
3263 * StringUtils.rightPad(null, *, *) = null
3264 * StringUtils.rightPad("", 3, "z") = "zzz"
3265 * StringUtils.rightPad("bat", 3, "yz") = "bat"
3266 * StringUtils.rightPad("bat", 5, "yz") = "batyz"
3267 * StringUtils.rightPad("bat", 8, "yz") = "batyzyzy"
3268 * StringUtils.rightPad("bat", 1, "yz") = "bat"
3269 * StringUtils.rightPad("bat", -1, "yz") = "bat"
3270 * StringUtils.rightPad("bat", 5, null) = "bat "
3271 * StringUtils.rightPad("bat", 5, "") = "bat "
3272 * </pre>
3273 *
3274 * @param str the String to pad out, may be null
3275 * @param size the size to pad to
3276 * @param padStr the String to pad with, null or empty treated as single sp ace
3277 * @return right padded String or original String if no padding is necessary ,
3278 * <code>null</code> if null String input
3279 */
3280 public static String rightPad(String str, int size, String padStr) {
3281 if (str == null) {
3282 return null;
3283 }
3284 if (isEmpty(padStr)) {
3285 padStr = " ";
3286 }
3287 int padLen = padStr.length();
3288 int strLen = str.length();
3289 int pads = size - strLen;
3290 if (pads <= 0) {
3291 return str; // returns original String when possible
3292 }
3293 if (padLen == 1 && pads <= PAD_LIMIT) {
3294 return rightPad(str, size, padStr.charAt(0));
3295 }
3296
3297 if (pads == padLen) {
3298 return str.concat(padStr);
3299 } else if (pads < padLen) {
3300 return str.concat(padStr.substring(0, pads));
3301 } else {
3302 char[] padding = new char[pads];
3303 char[] padChars = padStr.toCharArray();
3304 for (int i = 0; i < pads; i++) {
3305 padding[i] = padChars[i % padLen];
3306 }
3307 return str.concat(new String(padding));
3308 }
3309 }
3310
3311 /**
3312 * <p>Left pad a String with spaces (' ').</p>
3313 *
3314 * <p>The String is padded to the size of <code>size<code>.</p>
3315 *
3316 * <pre>
3317 * StringUtils.leftPad(null, *) = null
3318 * StringUtils.leftPad("", 3) = " "
3319 * StringUtils.leftPad("bat", 3) = "bat"
3320 * StringUtils.leftPad("bat", 5) = " bat"
3321 * StringUtils.leftPad("bat", 1) = "bat"
3322 * StringUtils.leftPad("bat", -1) = "bat"
3323 * </pre>
3324 *
3325 * @param str the String to pad out, may be null
3326 * @param size the size to pad to
3327 * @return left padded String or original String if no padding is necessary,
3328 * <code>null</code> if null String input
3329 */
3330 public static String leftPad(String str, int size) {
3331 return leftPad(str, size, ' ');
3332 }
3333
3334 /**
3335 * <p>Left pad a String with a specified character.</p>
3336 *
3337 * <p>Pad to a size of <code>size</code>.</p>
3338 *
3339 * <pre>
3340 * StringUtils.leftPad(null, *, *) = null
3341 * StringUtils.leftPad("", 3, 'z') = "zzz"
3342 * StringUtils.leftPad("bat", 3, 'z') = "bat"
3343 * StringUtils.leftPad("bat", 5, 'z') = "zzbat"
3344 * StringUtils.leftPad("bat", 1, 'z') = "bat"
3345 * StringUtils.leftPad("bat", -1, 'z') = "bat"
3346 * </pre>
3347 *
3348 * @param str the String to pad out, may be null
3349 * @param size the size to pad to
3350 * @param padChar the character to pad with
3351 * @return left padded String or original String if no padding is necessary,
3352 * <code>null</code> if null String input
3353 * @since 2.0
3354 */
3355 public static String leftPad(String str, int size, char padChar) {
3356 if (str == null) {
3357 return null;
3358 }
3359 int pads = size - str.length();
3360 if (pads <= 0) {
3361 return str; // returns original String when possible
3362 }
3363 if (pads > PAD_LIMIT) {
3364 return leftPad(str, size, String.valueOf(padChar));
3365 }
3366 return padding(pads, padChar).concat(str);
3367 }
3368
3369 /**
3370 * <p>Left pad a String with a specified String.</p>
3371 *
3372 * <p>Pad to a size of <code>size</code>.</p>
3373 *
3374 * <pre>
3375 * StringUtils.leftPad(null, *, *) = null
3376 * StringUtils.leftPad("", 3, "z") = "zzz"
3377 * StringUtils.leftPad("bat", 3, "yz") = "bat"
3378 * StringUtils.leftPad("bat", 5, "yz") = "yzbat"
3379 * StringUtils.leftPad("bat", 8, "yz") = "yzyzybat"
3380 * StringUtils.leftPad("bat", 1, "yz") = "bat"
3381 * StringUtils.leftPad("bat", -1, "yz") = "bat"
3382 * StringUtils.leftPad("bat", 5, null) = " bat"
3383 * StringUtils.leftPad("bat", 5, "") = " bat"
3384 * </pre>
3385 *
3386 * @param str the String to pad out, may be null
3387 * @param size the size to pad to
3388 * @param padStr the String to pad with, null or empty treated as single sp ace
3389 * @return left padded String or original String if no padding is necessary,
3390 * <code>null</code> if null String input
3391 */
3392 public static String leftPad(String str, int size, String padStr) {
3393 if (str == null) {
3394 return null;
3395 }
3396 if (isEmpty(padStr)) {
3397 padStr = " ";
3398 }
3399 int padLen = padStr.length();
3400 int strLen = str.length();
3401 int pads = size - strLen;
3402 if (pads <= 0) {
3403 return str; // returns original String when possible
3404 }
3405 if (padLen == 1 && pads <= PAD_LIMIT) {
3406 return leftPad(str, size, padStr.charAt(0));
3407 }
3408
3409 if (pads == padLen) {
3410 return padStr.concat(str);
3411 } else if (pads < padLen) {
3412 return padStr.substring(0, pads).concat(str);
3413 } else {
3414 char[] padding = new char[pads];
3415 char[] padChars = padStr.toCharArray();
3416 for (int i = 0; i < pads; i++) {
3417 padding[i] = padChars[i % padLen];
3418 }
3419 return new String(padding).concat(str);
3420 }
3421 }
3422
3423 /**
3424 * Gets a String's length or <code>0</code> if the String is <code>null</cod e>.
3425 *
3426 * @param str
3427 * a String or <code>null</code>
3428 * @return String length or <code>0</code> if the String is <code>null</code >.
3429 * @since 2.4
3430 */
3431 public static int length(String str) {
3432 return str == null ? 0 : str.length();
3433 }
3434
3435 // Centering
3436 //-----------------------------------------------------------------------
3437 /**
3438 * <p>Centers a String in a larger String of size <code>size</code>
3439 * using the space character (' ').<p>
3440 *
3441 * <p>If the size is less than the String length, the String is returned.
3442 * A <code>null</code> String returns <code>null</code>.
3443 * A negative size is treated as zero.</p>
3444 *
3445 * <p>Equivalent to <code>center(str, size, " ")</code>.</p>
3446 *
3447 * <pre>
3448 * StringUtils.center(null, *) = null
3449 * StringUtils.center("", 4) = " "
3450 * StringUtils.center("ab", -1) = "ab"
3451 * StringUtils.center("ab", 4) = " ab "
3452 * StringUtils.center("abcd", 2) = "abcd"
3453 * StringUtils.center("a", 4) = " a "
3454 * </pre>
3455 *
3456 * @param str the String to center, may be null
3457 * @param size the int size of new String, negative treated as zero
3458 * @return centered String, <code>null</code> if null String input
3459 */
3460 public static String center(String str, int size) {
3461 return center(str, size, ' ');
3462 }
3463
3464 /**
3465 * <p>Centers a String in a larger String of size <code>size</code>.
3466 * Uses a supplied character as the value to pad the String with.</p>
3467 *
3468 * <p>If the size is less than the String length, the String is returned.
3469 * A <code>null</code> String returns <code>null</code>.
3470 * A negative size is treated as zero.</p>
3471 *
3472 * <pre>
3473 * StringUtils.center(null, *, *) = null
3474 * StringUtils.center("", 4, ' ') = " "
3475 * StringUtils.center("ab", -1, ' ') = "ab"
3476 * StringUtils.center("ab", 4, ' ') = " ab"
3477 * StringUtils.center("abcd", 2, ' ') = "abcd"
3478 * StringUtils.center("a", 4, ' ') = " a "
3479 * StringUtils.center("a", 4, 'y') = "yayy"
3480 * </pre>
3481 *
3482 * @param str the String to center, may be null
3483 * @param size the int size of new String, negative treated as zero
3484 * @param padChar the character to pad the new String with
3485 * @return centered String, <code>null</code> if null String input
3486 * @since 2.0
3487 */
3488 public static String center(String str, int size, char padChar) {
3489 if (str == null || size <= 0) {
3490 return str;
3491 }
3492 int strLen = str.length();
3493 int pads = size - strLen;
3494 if (pads <= 0) {
3495 return str;
3496 }
3497 str = leftPad(str, strLen + pads / 2, padChar);
3498 str = rightPad(str, size, padChar);
3499 return str;
3500 }
3501
3502 /**
3503 * <p>Centers a String in a larger String of size <code>size</code>.
3504 * Uses a supplied String as the value to pad the String with.</p>
3505 *
3506 * <p>If the size is less than the String length, the String is returned.
3507 * A <code>null</code> String returns <code>null</code>.
3508 * A negative size is treated as zero.</p>
3509 *
3510 * <pre>
3511 * StringUtils.center(null, *, *) = null
3512 * StringUtils.center("", 4, " ") = " "
3513 * StringUtils.center("ab", -1, " ") = "ab"
3514 * StringUtils.center("ab", 4, " ") = " ab"
3515 * StringUtils.center("abcd", 2, " ") = "abcd"
3516 * StringUtils.center("a", 4, " ") = " a "
3517 * StringUtils.center("a", 4, "yz") = "yayz"
3518 * StringUtils.center("abc", 7, null) = " abc "
3519 * StringUtils.center("abc", 7, "") = " abc "
3520 * </pre>
3521 *
3522 * @param str the String to center, may be null
3523 * @param size the int size of new String, negative treated as zero
3524 * @param padStr the String to pad the new String with, must not be null or empty
3525 * @return centered String, <code>null</code> if null String input
3526 * @throws IllegalArgumentException if padStr is <code>null</code> or empty
3527 */
3528 public static String center(String str, int size, String padStr) {
3529 if (str == null || size <= 0) {
3530 return str;
3531 }
3532 if (isEmpty(padStr)) {
3533 padStr = " ";
3534 }
3535 int strLen = str.length();
3536 int pads = size - strLen;
3537 if (pads <= 0) {
3538 return str;
3539 }
3540 str = leftPad(str, strLen + pads / 2, padStr);
3541 str = rightPad(str, size, padStr);
3542 return str;
3543 }
3544
3545 // Case conversion
3546 //-----------------------------------------------------------------------
3547 /**
3548 * <p>Converts a String to upper case as per {@link String#toUpperCase()}.</ p>
3549 *
3550 * <p>A <code>null</code> input String returns <code>null</code>.</p>
3551 *
3552 * <pre>
3553 * StringUtils.upperCase(null) = null
3554 * StringUtils.upperCase("") = ""
3555 * StringUtils.upperCase("aBc") = "ABC"
3556 * </pre>
3557 *
3558 * @param str the String to upper case, may be null
3559 * @return the upper cased String, <code>null</code> if null String input
3560 */
3561 public static String upperCase(String str) {
3562 if (str == null) {
3563 return null;
3564 }
3565 return str.toUpperCase();
3566 }
3567
3568 /**
3569 * <p>Converts a String to lower case as per {@link String#toLowerCase()}.</ p>
3570 *
3571 * <p>A <code>null</code> input String returns <code>null</code>.</p>
3572 *
3573 * <pre>
3574 * StringUtils.lowerCase(null) = null
3575 * StringUtils.lowerCase("") = ""
3576 * StringUtils.lowerCase("aBc") = "abc"
3577 * </pre>
3578 *
3579 * @param str the String to lower case, may be null
3580 * @return the lower cased String, <code>null</code> if null String input
3581 */
3582 public static String lowerCase(String str) {
3583 if (str == null) {
3584 return null;
3585 }
3586 return str.toLowerCase();
3587 }
3588
3589 /**
3590 * <p>Capitalizes a String changing the first letter to title case as
3591 * per {@link Character#toTitleCase(char)}. No other letters are changed.</p >
3592 *
3593 * <p>For a word based algorithm, see {@link WordUtils#capitalize(String)}.
3594 * A <code>null</code> input String returns <code>null</code>.</p>
3595 *
3596 * <pre>
3597 * StringUtils.capitalize(null) = null
3598 * StringUtils.capitalize("") = ""
3599 * StringUtils.capitalize("cat") = "Cat"
3600 * StringUtils.capitalize("cAt") = "CAt"
3601 * </pre>
3602 *
3603 * @param str the String to capitalize, may be null
3604 * @return the capitalized String, <code>null</code> if null String input
3605 * @see WordUtils#capitalize(String)
3606 * @see #uncapitalize(String)
3607 * @since 2.0
3608 */
3609 public static String capitalize(String str) {
3610 int strLen;
3611 if (str == null || (strLen = str.length()) == 0) {
3612 return str;
3613 }
3614 return new StringBuffer(strLen)
3615 .append(Character.toTitleCase(str.charAt(0)))
3616 .append(str.substring(1))
3617 .toString();
3618 }
3619
3620 /**
3621 * <p>Capitalizes a String changing the first letter to title case as
3622 * per {@link Character#toTitleCase(char)}. No other letters are changed.</p >
3623 *
3624 * @param str the String to capitalize, may be null
3625 * @return the capitalized String, <code>null</code> if null String input
3626 * @deprecated Use the standardly named {@link #capitalize(String)}.
3627 * Method will be removed in Commons Lang 3.0.
3628 */
3629 public static String capitalise(String str) {
3630 return capitalize(str);
3631 }
3632
3633 /**
3634 * <p>Uncapitalizes a String changing the first letter to title case as
3635 * per {@link Character#toLowerCase(char)}. No other letters are changed.</p >
3636 *
3637 * <p>For a word based algorithm, see {@link WordUtils#uncapitalize(String)} .
3638 * A <code>null</code> input String returns <code>null</code>.</p>
3639 *
3640 * <pre>
3641 * StringUtils.uncapitalize(null) = null
3642 * StringUtils.uncapitalize("") = ""
3643 * StringUtils.uncapitalize("Cat") = "cat"
3644 * StringUtils.uncapitalize("CAT") = "cAT"
3645 * </pre>
3646 *
3647 * @param str the String to uncapitalize, may be null
3648 * @return the uncapitalized String, <code>null</code> if null String input
3649 * @see WordUtils#uncapitalize(String)
3650 * @see #capitalize(String)
3651 * @since 2.0
3652 */
3653 public static String uncapitalize(String str) {
3654 int strLen;
3655 if (str == null || (strLen = str.length()) == 0) {
3656 return str;
3657 }
3658 return new StringBuffer(strLen)
3659 .append(Character.toLowerCase(str.charAt(0)))
3660 .append(str.substring(1))
3661 .toString();
3662 }
3663
3664 /**
3665 * <p>Uncapitalizes a String changing the first letter to title case as
3666 * per {@link Character#toLowerCase(char)}. No other letters are changed.</p >
3667 *
3668 * @param str the String to uncapitalize, may be null
3669 * @return the uncapitalized String, <code>null</code> if null String input
3670 * @deprecated Use the standardly named {@link #uncapitalize(String)}.
3671 * Method will be removed in Commons Lang 3.0.
3672 */
3673 public static String uncapitalise(String str) {
3674 return uncapitalize(str);
3675 }
3676
3677 /**
3678 * <p>Swaps the case of a String changing upper and title case to
3679 * lower case, and lower case to upper case.</p>
3680 *
3681 * <ul>
3682 * <li>Upper case character converts to Lower case</li>
3683 * <li>Title case character converts to Lower case</li>
3684 * <li>Lower case character converts to Upper case</li>
3685 * </ul>
3686 *
3687 * <p>For a word based algorithm, see {@link WordUtils#swapCase(String)}.
3688 * A <code>null</code> input String returns <code>null</code>.</p>
3689 *
3690 * <pre>
3691 * StringUtils.swapCase(null) = null
3692 * StringUtils.swapCase("") = ""
3693 * StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
3694 * </pre>
3695 *
3696 * <p>NOTE: This method changed in Lang version 2.0.
3697 * It no longer performs a word based algorithm.
3698 * If you only use ASCII, you will notice no change.
3699 * That functionality is available in WordUtils.</p>
3700 *
3701 * @param str the String to swap case, may be null
3702 * @return the changed String, <code>null</code> if null String input
3703 */
3704 public static String swapCase(String str) {
3705 int strLen;
3706 if (str == null || (strLen = str.length()) == 0) {
3707 return str;
3708 }
3709 StringBuffer buffer = new StringBuffer(strLen);
3710
3711 char ch = 0;
3712 for (int i = 0; i < strLen; i++) {
3713 ch = str.charAt(i);
3714 if (Character.isUpperCase(ch)) {
3715 ch = Character.toLowerCase(ch);
3716 } else if (Character.isTitleCase(ch)) {
3717 ch = Character.toLowerCase(ch);
3718 } else if (Character.isLowerCase(ch)) {
3719 ch = Character.toUpperCase(ch);
3720 }
3721 buffer.append(ch);
3722 }
3723 return buffer.toString();
3724 }
3725
3726 // Count matches
3727 //-----------------------------------------------------------------------
3728 /**
3729 * <p>Counts how many times the substring appears in the larger String.</p>
3730 *
3731 * <p>A <code>null</code> or empty ("") String input returns <code>0</code>. </p>
3732 *
3733 * <pre>
3734 * StringUtils.countMatches(null, *) = 0
3735 * StringUtils.countMatches("", *) = 0
3736 * StringUtils.countMatches("abba", null) = 0
3737 * StringUtils.countMatches("abba", "") = 0
3738 * StringUtils.countMatches("abba", "a") = 2
3739 * StringUtils.countMatches("abba", "ab") = 1
3740 * StringUtils.countMatches("abba", "xxx") = 0
3741 * </pre>
3742 *
3743 * @param str the String to check, may be null
3744 * @param sub the substring to count, may be null
3745 * @return the number of occurrences, 0 if either String is <code>null</code >
3746 */
3747 public static int countMatches(String str, String sub) {
3748 if (isEmpty(str) || isEmpty(sub)) {
3749 return 0;
3750 }
3751 int count = 0;
3752 int idx = 0;
3753 while ((idx = str.indexOf(sub, idx)) != -1) {
3754 count++;
3755 idx += sub.length();
3756 }
3757 return count;
3758 }
3759
3760 // Character Tests
3761 //-----------------------------------------------------------------------
3762 /**
3763 * <p>Checks if the String contains only unicode letters.</p>
3764 *
3765 * <p><code>null</code> will return <code>false</code>.
3766 * An empty String ("") will return <code>true</code>.</p>
3767 *
3768 * <pre>
3769 * StringUtils.isAlpha(null) = false
3770 * StringUtils.isAlpha("") = true
3771 * StringUtils.isAlpha(" ") = false
3772 * StringUtils.isAlpha("abc") = true
3773 * StringUtils.isAlpha("ab2c") = false
3774 * StringUtils.isAlpha("ab-c") = false
3775 * </pre>
3776 *
3777 * @param str the String to check, may be null
3778 * @return <code>true</code> if only contains letters, and is non-null
3779 */
3780 public static boolean isAlpha(String str) {
3781 if (str == null) {
3782 return false;
3783 }
3784 int sz = str.length();
3785 for (int i = 0; i < sz; i++) {
3786 if (Character.isLetter(str.charAt(i)) == false) {
3787 return false;
3788 }
3789 }
3790 return true;
3791 }
3792
3793 /**
3794 * <p>Checks if the String contains only unicode letters and
3795 * space (' ').</p>
3796 *
3797 * <p><code>null</code> will return <code>false</code>
3798 * An empty String ("") will return <code>true</code>.</p>
3799 *
3800 * <pre>
3801 * StringUtils.isAlphaSpace(null) = false
3802 * StringUtils.isAlphaSpace("") = true
3803 * StringUtils.isAlphaSpace(" ") = true
3804 * StringUtils.isAlphaSpace("abc") = true
3805 * StringUtils.isAlphaSpace("ab c") = true
3806 * StringUtils.isAlphaSpace("ab2c") = false
3807 * StringUtils.isAlphaSpace("ab-c") = false
3808 * </pre>
3809 *
3810 * @param str the String to check, may be null
3811 * @return <code>true</code> if only contains letters and space,
3812 * and is non-null
3813 */
3814 public static boolean isAlphaSpace(String str) {
3815 if (str == null) {
3816 return false;
3817 }
3818 int sz = str.length();
3819 for (int i = 0; i < sz; i++) {
3820 if ((Character.isLetter(str.charAt(i)) == false) && (str.charAt(i) ! = ' ')) {
3821 return false;
3822 }
3823 }
3824 return true;
3825 }
3826
3827 /**
3828 * <p>Checks if the String contains only unicode letters or digits.</p>
3829 *
3830 * <p><code>null</code> will return <code>false</code>.
3831 * An empty String ("") will return <code>true</code>.</p>
3832 *
3833 * <pre>
3834 * StringUtils.isAlphanumeric(null) = false
3835 * StringUtils.isAlphanumeric("") = true
3836 * StringUtils.isAlphanumeric(" ") = false
3837 * StringUtils.isAlphanumeric("abc") = true
3838 * StringUtils.isAlphanumeric("ab c") = false
3839 * StringUtils.isAlphanumeric("ab2c") = true
3840 * StringUtils.isAlphanumeric("ab-c") = false
3841 * </pre>
3842 *
3843 * @param str the String to check, may be null
3844 * @return <code>true</code> if only contains letters or digits,
3845 * and is non-null
3846 */
3847 public static boolean isAlphanumeric(String str) {
3848 if (str == null) {
3849 return false;
3850 }
3851 int sz = str.length();
3852 for (int i = 0; i < sz; i++) {
3853 if (Character.isLetterOrDigit(str.charAt(i)) == false) {
3854 return false;
3855 }
3856 }
3857 return true;
3858 }
3859
3860 /**
3861 * <p>Checks if the String contains only unicode letters, digits
3862 * or space (<code>' '</code>).</p>
3863 *
3864 * <p><code>null</code> will return <code>false</code>.
3865 * An empty String ("") will return <code>true</code>.</p>
3866 *
3867 * <pre>
3868 * StringUtils.isAlphanumeric(null) = false
3869 * StringUtils.isAlphanumeric("") = true
3870 * StringUtils.isAlphanumeric(" ") = true
3871 * StringUtils.isAlphanumeric("abc") = true
3872 * StringUtils.isAlphanumeric("ab c") = true
3873 * StringUtils.isAlphanumeric("ab2c") = true
3874 * StringUtils.isAlphanumeric("ab-c") = false
3875 * </pre>
3876 *
3877 * @param str the String to check, may be null
3878 * @return <code>true</code> if only contains letters, digits or space,
3879 * and is non-null
3880 */
3881 public static boolean isAlphanumericSpace(String str) {
3882 if (str == null) {
3883 return false;
3884 }
3885 int sz = str.length();
3886 for (int i = 0; i < sz; i++) {
3887 if ((Character.isLetterOrDigit(str.charAt(i)) == false) && (str.char At(i) != ' ')) {
3888 return false;
3889 }
3890 }
3891 return true;
3892 }
3893
3894 /**
3895 * <p>Checks if the string contains only ASCII printable characters.</p>
3896 *
3897 * <p><code>null</code> will return <code>false</code>.
3898 * An empty String ("") will return <code>true</code>.</p>
3899 *
3900 * <pre>
3901 * StringUtils.isAsciiPrintable(null) = false
3902 * StringUtils.isAsciiPrintable("") = true
3903 * StringUtils.isAsciiPrintable(" ") = true
3904 * StringUtils.isAsciiPrintable("Ceki") = true
3905 * StringUtils.isAsciiPrintable("ab2c") = true
3906 * StringUtils.isAsciiPrintable("!ab-c~") = true
3907 * StringUtils.isAsciiPrintable("\u0020") = true
3908 * StringUtils.isAsciiPrintable("\u0021") = true
3909 * StringUtils.isAsciiPrintable("\u007e") = true
3910 * StringUtils.isAsciiPrintable("\u007f") = false
3911 * StringUtils.isAsciiPrintable("Ceki G\u00fclc\u00fc") = false
3912 * </pre>
3913 *
3914 * @param str the string to check, may be null
3915 * @return <code>true</code> if every character is in the range
3916 * 32 thru 126
3917 * @since 2.1
3918 */
3919 public static boolean isAsciiPrintable(String str) {
3920 if (str == null) {
3921 return false;
3922 }
3923 int sz = str.length();
3924 for (int i = 0; i < sz; i++) {
3925 if (CharUtils.isAsciiPrintable(str.charAt(i)) == false) {
3926 return false;
3927 }
3928 }
3929 return true;
3930 }
3931
3932 /**
3933 * <p>Checks if the String contains only unicode digits.
3934 * A decimal point is not a unicode digit and returns false.</p>
3935 *
3936 * <p><code>null</code> will return <code>false</code>.
3937 * An empty String ("") will return <code>true</code>.</p>
3938 *
3939 * <pre>
3940 * StringUtils.isNumeric(null) = false
3941 * StringUtils.isNumeric("") = true
3942 * StringUtils.isNumeric(" ") = false
3943 * StringUtils.isNumeric("123") = true
3944 * StringUtils.isNumeric("12 3") = false
3945 * StringUtils.isNumeric("ab2c") = false
3946 * StringUtils.isNumeric("12-3") = false
3947 * StringUtils.isNumeric("12.3") = false
3948 * </pre>
3949 *
3950 * @param str the String to check, may be null
3951 * @return <code>true</code> if only contains digits, and is non-null
3952 */
3953 public static boolean isNumeric(String str) {
3954 if (str == null) {
3955 return false;
3956 }
3957 int sz = str.length();
3958 for (int i = 0; i < sz; i++) {
3959 if (Character.isDigit(str.charAt(i)) == false) {
3960 return false;
3961 }
3962 }
3963 return true;
3964 }
3965
3966 /**
3967 * <p>Checks if the String contains only unicode digits or space
3968 * (<code>' '</code>).
3969 * A decimal point is not a unicode digit and returns false.</p>
3970 *
3971 * <p><code>null</code> will return <code>false</code>.
3972 * An empty String ("") will return <code>true</code>.</p>
3973 *
3974 * <pre>
3975 * StringUtils.isNumeric(null) = false
3976 * StringUtils.isNumeric("") = true
3977 * StringUtils.isNumeric(" ") = true
3978 * StringUtils.isNumeric("123") = true
3979 * StringUtils.isNumeric("12 3") = true
3980 * StringUtils.isNumeric("ab2c") = false
3981 * StringUtils.isNumeric("12-3") = false
3982 * StringUtils.isNumeric("12.3") = false
3983 * </pre>
3984 *
3985 * @param str the String to check, may be null
3986 * @return <code>true</code> if only contains digits or space,
3987 * and is non-null
3988 */
3989 public static boolean isNumericSpace(String str) {
3990 if (str == null) {
3991 return false;
3992 }
3993 int sz = str.length();
3994 for (int i = 0; i < sz; i++) {
3995 if ((Character.isDigit(str.charAt(i)) == false) && (str.charAt(i) != ' ')) {
3996 return false;
3997 }
3998 }
3999 return true;
4000 }
4001
4002 /**
4003 * <p>Checks if the String contains only whitespace.</p>
4004 *
4005 * <p><code>null</code> will return <code>false</code>.
4006 * An empty String ("") will return <code>true</code>.</p>
4007 *
4008 * <pre>
4009 * StringUtils.isWhitespace(null) = false
4010 * StringUtils.isWhitespace("") = true
4011 * StringUtils.isWhitespace(" ") = true
4012 * StringUtils.isWhitespace("abc") = false
4013 * StringUtils.isWhitespace("ab2c") = false
4014 * StringUtils.isWhitespace("ab-c") = false
4015 * </pre>
4016 *
4017 * @param str the String to check, may be null
4018 * @return <code>true</code> if only contains whitespace, and is non-null
4019 * @since 2.0
4020 */
4021 public static boolean isWhitespace(String str) {
4022 if (str == null) {
4023 return false;
4024 }
4025 int sz = str.length();
4026 for (int i = 0; i < sz; i++) {
4027 if ((Character.isWhitespace(str.charAt(i)) == false)) {
4028 return false;
4029 }
4030 }
4031 return true;
4032 }
4033
4034 // Defaults
4035 //-----------------------------------------------------------------------
4036 /**
4037 * <p>Returns either the passed in String,
4038 * or if the String is <code>null</code>, an empty String ("").</p>
4039 *
4040 * <pre>
4041 * StringUtils.defaultString(null) = ""
4042 * StringUtils.defaultString("") = ""
4043 * StringUtils.defaultString("bat") = "bat"
4044 * </pre>
4045 *
4046 * @see ObjectUtils#toString(Object)
4047 * @see String#valueOf(Object)
4048 * @param str the String to check, may be null
4049 * @return the passed in String, or the empty String if it
4050 * was <code>null</code>
4051 */
4052 public static String defaultString(String str) {
4053 return str == null ? EMPTY : str;
4054 }
4055
4056 /**
4057 * <p>Returns either the passed in String, or if the String is
4058 * <code>null</code>, the value of <code>defaultStr</code>.</p>
4059 *
4060 * <pre>
4061 * StringUtils.defaultString(null, "NULL") = "NULL"
4062 * StringUtils.defaultString("", "NULL") = ""
4063 * StringUtils.defaultString("bat", "NULL") = "bat"
4064 * </pre>
4065 *
4066 * @see ObjectUtils#toString(Object,String)
4067 * @see String#valueOf(Object)
4068 * @param str the String to check, may be null
4069 * @param defaultStr the default String to return
4070 * if the input is <code>null</code>, may be null
4071 * @return the passed in String, or the default if it was <code>null</code>
4072 */
4073 public static String defaultString(String str, String defaultStr) {
4074 return str == null ? defaultStr : str;
4075 }
4076
4077 /**
4078 * <p>Returns either the passed in String, or if the String is
4079 * empty or <code>null</code>, the value of <code>defaultStr</code>.</p>
4080 *
4081 * <pre>
4082 * StringUtils.defaultIfEmpty(null, "NULL") = "NULL"
4083 * StringUtils.defaultIfEmpty("", "NULL") = "NULL"
4084 * StringUtils.defaultIfEmpty("bat", "NULL") = "bat"
4085 * </pre>
4086 *
4087 * @see StringUtils#defaultString(String, String)
4088 * @param str the String to check, may be null
4089 * @param defaultStr the default String to return
4090 * if the input is empty ("") or <code>null</code>, may be null
4091 * @return the passed in String, or the default
4092 */
4093 public static String defaultIfEmpty(String str, String defaultStr) {
4094 return StringUtils.isEmpty(str) ? defaultStr : str;
4095 }
4096
4097 // Reversing
4098 //-----------------------------------------------------------------------
4099 /**
4100 * <p>Reverses a String as per {@link StringBuffer#reverse()}.</p>
4101 *
4102 * <p>A <code>null</code> String returns <code>null</code>.</p>
4103 *
4104 * <pre>
4105 * StringUtils.reverse(null) = null
4106 * StringUtils.reverse("") = ""
4107 * StringUtils.reverse("bat") = "tab"
4108 * </pre>
4109 *
4110 * @param str the String to reverse, may be null
4111 * @return the reversed String, <code>null</code> if null String input
4112 */
4113 public static String reverse(String str) {
4114 if (str == null) {
4115 return null;
4116 }
4117 return new StringBuffer(str).reverse().toString();
4118 }
4119
4120 // Abbreviating
4121 //-----------------------------------------------------------------------
4122 /**
4123 * <p>Abbreviates a String using ellipses. This will turn
4124 * "Now is the time for all good men" into "Now is the time for..."</p>
4125 *
4126 * <p>Specifically:
4127 * <ul>
4128 * <li>If <code>str</code> is less than <code>maxWidth</code> characters
4129 * long, return it.</li>
4130 * <li>Else abbreviate it to <code>(substring(str, 0, max-3) + "...")</cod e>.</li>
4131 * <li>If <code>maxWidth</code> is less than <code>4</code>, throw an
4132 * <code>IllegalArgumentException</code>.</li>
4133 * <li>In no case will it return a String of length greater than
4134 * <code>maxWidth</code>.</li>
4135 * </ul>
4136 * </p>
4137 *
4138 * <pre>
4139 * StringUtils.abbreviate(null, *) = null
4140 * StringUtils.abbreviate("", 4) = ""
4141 * StringUtils.abbreviate("abcdefg", 6) = "abc..."
4142 * StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
4143 * StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
4144 * StringUtils.abbreviate("abcdefg", 4) = "a..."
4145 * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException
4146 * </pre>
4147 *
4148 * @param str the String to check, may be null
4149 * @param maxWidth maximum length of result String, must be at least 4
4150 * @return abbreviated String, <code>null</code> if null String input
4151 * @throws IllegalArgumentException if the width is too small
4152 * @since 2.0
4153 */
4154 public static String abbreviate(String str, int maxWidth) {
4155 return abbreviate(str, 0, maxWidth);
4156 }
4157
4158 /**
4159 * <p>Abbreviates a String using ellipses. This will turn
4160 * "Now is the time for all good men" into "...is the time for..."</p>
4161 *
4162 * <p>Works like <code>abbreviate(String, int)</code>, but allows you to spe cify
4163 * a "left edge" offset. Note that this left edge is not necessarily going to
4164 * be the leftmost character in the result, or the first character following the
4165 * ellipses, but it will appear somewhere in the result.
4166 *
4167 * <p>In no case will it return a String of length greater than
4168 * <code>maxWidth</code>.</p>
4169 *
4170 * <pre>
4171 * StringUtils.abbreviate(null, *, *) = null
4172 * StringUtils.abbreviate("", 0, 4) = ""
4173 * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
4174 * StringUtils.abbreviate("abcdefghijklmno", 0, 10) = "abcdefg..."
4175 * StringUtils.abbreviate("abcdefghijklmno", 1, 10) = "abcdefg..."
4176 * StringUtils.abbreviate("abcdefghijklmno", 4, 10) = "abcdefg..."
4177 * StringUtils.abbreviate("abcdefghijklmno", 5, 10) = "...fghi..."
4178 * StringUtils.abbreviate("abcdefghijklmno", 6, 10) = "...ghij..."
4179 * StringUtils.abbreviate("abcdefghijklmno", 8, 10) = "...ijklmno"
4180 * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
4181 * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
4182 * StringUtils.abbreviate("abcdefghij", 0, 3) = IllegalArgumentExcept ion
4183 * StringUtils.abbreviate("abcdefghij", 5, 6) = IllegalArgumentExcept ion
4184 * </pre>
4185 *
4186 * @param str the String to check, may be null
4187 * @param offset left edge of source String
4188 * @param maxWidth maximum length of result String, must be at least 4
4189 * @return abbreviated String, <code>null</code> if null String input
4190 * @throws IllegalArgumentException if the width is too small
4191 * @since 2.0
4192 */
4193 public static String abbreviate(String str, int offset, int maxWidth) {
4194 if (str == null) {
4195 return null;
4196 }
4197 if (maxWidth < 4) {
4198 throw new IllegalArgumentException("Minimum abbreviation width is 4" );
4199 }
4200 if (str.length() <= maxWidth) {
4201 return str;
4202 }
4203 if (offset > str.length()) {
4204 offset = str.length();
4205 }
4206 if ((str.length() - offset) < (maxWidth - 3)) {
4207 offset = str.length() - (maxWidth - 3);
4208 }
4209 if (offset <= 4) {
4210 return str.substring(0, maxWidth - 3) + "...";
4211 }
4212 if (maxWidth < 7) {
4213 throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
4214 }
4215 if ((offset + (maxWidth - 3)) < str.length()) {
4216 return "..." + abbreviate(str.substring(offset), maxWidth - 3);
4217 }
4218 return "..." + str.substring(str.length() - (maxWidth - 3));
4219 }
4220
4221 // Difference
4222 //-----------------------------------------------------------------------
4223 /**
4224 * <p>Compares two Strings, and returns the portion where they differ.
4225 * (More precisely, return the remainder of the second String,
4226 * starting from where it's different from the first.)</p>
4227 *
4228 * <p>For example,
4229 * <code>difference("i am a machine", "i am a robot") -> "robot"</code>.</p>
4230 *
4231 * <pre>
4232 * StringUtils.difference(null, null) = null
4233 * StringUtils.difference("", "") = ""
4234 * StringUtils.difference("", "abc") = "abc"
4235 * StringUtils.difference("abc", "") = ""
4236 * StringUtils.difference("abc", "abc") = ""
4237 * StringUtils.difference("ab", "abxyz") = "xyz"
4238 * StringUtils.difference("abcde", "abxyz") = "xyz"
4239 * StringUtils.difference("abcde", "xyz") = "xyz"
4240 * </pre>
4241 *
4242 * @param str1 the first String, may be null
4243 * @param str2 the second String, may be null
4244 * @return the portion of str2 where it differs from str1; returns the
4245 * empty String if they are equal
4246 * @since 2.0
4247 */
4248 public static String difference(String str1, String str2) {
4249 if (str1 == null) {
4250 return str2;
4251 }
4252 if (str2 == null) {
4253 return str1;
4254 }
4255 int at = indexOfDifference(str1, str2);
4256 if (at == -1) {
4257 return EMPTY;
4258 }
4259 return str2.substring(at);
4260 }
4261
4262 /**
4263 * <p>Compares two Strings, and returns the index at which the
4264 * Strings begin to differ.</p>
4265 *
4266 * <p>For example,
4267 * <code>indexOfDifference("i am a machine", "i am a robot") -> 7</code></p>
4268 *
4269 * <pre>
4270 * StringUtils.indexOfDifference(null, null) = -1
4271 * StringUtils.indexOfDifference("", "") = -1
4272 * StringUtils.indexOfDifference("", "abc") = 0
4273 * StringUtils.indexOfDifference("abc", "") = 0
4274 * StringUtils.indexOfDifference("abc", "abc") = -1
4275 * StringUtils.indexOfDifference("ab", "abxyz") = 2
4276 * StringUtils.indexOfDifference("abcde", "abxyz") = 2
4277 * StringUtils.indexOfDifference("abcde", "xyz") = 0
4278 * </pre>
4279 *
4280 * @param str1 the first String, may be null
4281 * @param str2 the second String, may be null
4282 * @return the index where str2 and str1 begin to differ; -1 if they are equ al
4283 * @since 2.0
4284 */
4285 public static int indexOfDifference(String str1, String str2) {
4286 if (str1 == str2) {
4287 return -1;
4288 }
4289 if (str1 == null || str2 == null) {
4290 return 0;
4291 }
4292 int i;
4293 for (i = 0; i < str1.length() && i < str2.length(); ++i) {
4294 if (str1.charAt(i) != str2.charAt(i)) {
4295 break;
4296 }
4297 }
4298 if (i < str2.length() || i < str1.length()) {
4299 return i;
4300 }
4301 return -1;
4302 }
4303
4304 /**
4305 * <p>Compares all Strings in an array and returns the index at which the
4306 * Strings begin to differ.</p>
4307 *
4308 * <p>For example,
4309 * <code>indexOfDifference(new String[] {"i am a machine", "i am a robot"}) -> 7</code></p>
4310 *
4311 * <pre>
4312 * StringUtils.indexOfDifference(null) = -1
4313 * StringUtils.indexOfDifference(new String[] {}) = -1
4314 * StringUtils.indexOfDifference(new String[] {"abc"}) = -1
4315 * StringUtils.indexOfDifference(new String[] {null, null}) = -1
4316 * StringUtils.indexOfDifference(new String[] {"", ""}) = -1
4317 * StringUtils.indexOfDifference(new String[] {"", null}) = 0
4318 * StringUtils.indexOfDifference(new String[] {"abc", null, null}) = 0
4319 * StringUtils.indexOfDifference(new String[] {null, null, "abc"}) = 0
4320 * StringUtils.indexOfDifference(new String[] {"", "abc"}) = 0
4321 * StringUtils.indexOfDifference(new String[] {"abc", ""}) = 0
4322 * StringUtils.indexOfDifference(new String[] {"abc", "abc"}) = -1
4323 * StringUtils.indexOfDifference(new String[] {"abc", "a"}) = 1
4324 * StringUtils.indexOfDifference(new String[] {"ab", "abxyz"}) = 2
4325 * StringUtils.indexOfDifference(new String[] {"abcde", "abxyz"}) = 2
4326 * StringUtils.indexOfDifference(new String[] {"abcde", "xyz"}) = 0
4327 * StringUtils.indexOfDifference(new String[] {"xyz", "abcde"}) = 0
4328 * StringUtils.indexOfDifference(new String[] {"i am a machine", "i am a rob ot"}) = 7
4329 * </pre>
4330 *
4331 * @param strs array of strings, entries may be null
4332 * @return the index where the strings begin to differ; -1 if they are all e qual
4333 * @since 2.4
4334 */
4335 public static int indexOfDifference(String[] strs) {
4336 if (strs == null || strs.length <= 1) {
4337 return -1;
4338 }
4339 boolean anyStringNull = false;
4340 boolean allStringsNull = true;
4341 int arrayLen = strs.length;
4342 int shortestStrLen = Integer.MAX_VALUE;
4343 int longestStrLen = 0;
4344
4345 // find the min and max string lengths; this avoids checking to make
4346 // sure we are not exceeding the length of the string each time through
4347 // the bottom loop.
4348 for (int i = 0; i < arrayLen; i++) {
4349 if (strs[i] == null) {
4350 anyStringNull = true;
4351 shortestStrLen = 0;
4352 } else {
4353 allStringsNull = false;
4354 shortestStrLen = Math.min(strs[i].length(), shortestStrLen);
4355 longestStrLen = Math.max(strs[i].length(), longestStrLen);
4356 }
4357 }
4358
4359 // handle lists containing all nulls or all empty strings
4360 if (allStringsNull || (longestStrLen == 0 && !anyStringNull)) {
4361 return -1;
4362 }
4363
4364 // handle lists containing some nulls or some empty strings
4365 if (shortestStrLen == 0) {
4366 return 0;
4367 }
4368
4369 // find the position with the first difference across all strings
4370 int firstDiff = -1;
4371 for (int stringPos = 0; stringPos < shortestStrLen; stringPos++) {
4372 char comparisonChar = strs[0].charAt(stringPos);
4373 for (int arrayPos = 1; arrayPos < arrayLen; arrayPos++) {
4374 if (strs[arrayPos].charAt(stringPos) != comparisonChar) {
4375 firstDiff = stringPos;
4376 break;
4377 }
4378 }
4379 if (firstDiff != -1) {
4380 break;
4381 }
4382 }
4383
4384 if (firstDiff == -1 && shortestStrLen != longestStrLen) {
4385 // we compared all of the characters up to the length of the
4386 // shortest string and didn't find a match, but the string lengths
4387 // vary, so return the length of the shortest string.
4388 return shortestStrLen;
4389 }
4390 return firstDiff;
4391 }
4392
4393 /**
4394 * <p>Compares all Strings in an array and returns the initial sequence of
4395 * characters that is common to all of them.</p>
4396 *
4397 * <p>For example,
4398 * <code>getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) -> "i am a "</code></p>
4399 *
4400 * <pre>
4401 * StringUtils.getCommonPrefix(null) = ""
4402 * StringUtils.getCommonPrefix(new String[] {}) = ""
4403 * StringUtils.getCommonPrefix(new String[] {"abc"}) = "abc"
4404 * StringUtils.getCommonPrefix(new String[] {null, null}) = ""
4405 * StringUtils.getCommonPrefix(new String[] {"", ""}) = ""
4406 * StringUtils.getCommonPrefix(new String[] {"", null}) = ""
4407 * StringUtils.getCommonPrefix(new String[] {"abc", null, null}) = ""
4408 * StringUtils.getCommonPrefix(new String[] {null, null, "abc"}) = ""
4409 * StringUtils.getCommonPrefix(new String[] {"", "abc"}) = ""
4410 * StringUtils.getCommonPrefix(new String[] {"abc", ""}) = ""
4411 * StringUtils.getCommonPrefix(new String[] {"abc", "abc"}) = "abc"
4412 * StringUtils.getCommonPrefix(new String[] {"abc", "a"}) = "a"
4413 * StringUtils.getCommonPrefix(new String[] {"ab", "abxyz"}) = "ab"
4414 * StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"
4415 * StringUtils.getCommonPrefix(new String[] {"abcde", "xyz"}) = ""
4416 * StringUtils.getCommonPrefix(new String[] {"xyz", "abcde"}) = ""
4417 * StringUtils.getCommonPrefix(new String[] {"i am a machine", "i am a robot "}) = "i am a "
4418 * </pre>
4419 *
4420 * @param strs array of String objects, entries may be null
4421 * @return the initial sequence of characters that are common to all Strings
4422 * in the array; empty String if the array is null, the elements are all nul l
4423 * or if there is no common prefix.
4424 * @since 2.4
4425 */
4426 public static String getCommonPrefix(String[] strs) {
4427 if (strs == null || strs.length == 0) {
4428 return EMPTY;
4429 }
4430 int smallestIndexOfDiff = indexOfDifference(strs);
4431 if (smallestIndexOfDiff == -1) {
4432 // all strings were identical
4433 if (strs[0] == null) {
4434 return EMPTY;
4435 }
4436 return strs[0];
4437 } else if (smallestIndexOfDiff == 0) {
4438 // there were no common initial characters
4439 return EMPTY;
4440 } else {
4441 // we found a common initial character sequence
4442 return strs[0].substring(0, smallestIndexOfDiff);
4443 }
4444 }
4445
4446 // Misc
4447 //-----------------------------------------------------------------------
4448 /**
4449 * <p>Find the Levenshtein distance between two Strings.</p>
4450 *
4451 * <p>This is the number of changes needed to change one String into
4452 * another, where each change is a single character modification (deletion,
4453 * insertion or substitution).</p>
4454 *
4455 * <p>The previous implementation of the Levenshtein distance algorithm
4456 * was from <a href="http://www.merriampark.com/ld.htm">http://www.merriampa rk.com/ld.htm</a></p>
4457 *
4458 * <p>Chas Emerick has written an implementation in Java, which avoids an Ou tOfMemoryError
4459 * which can occur when my Java implementation is used with very large strin gs.<br>
4460 * This implementation of the Levenshtein distance algorithm
4461 * is from <a href="http://www.merriampark.com/ldjava.htm">http://www.merria mpark.com/ldjava.htm</a></p>
4462 *
4463 * <pre>
4464 * StringUtils.getLevenshteinDistance(null, *) = IllegalArgument Exception
4465 * StringUtils.getLevenshteinDistance(*, null) = IllegalArgument Exception
4466 * StringUtils.getLevenshteinDistance("","") = 0
4467 * StringUtils.getLevenshteinDistance("","a") = 1
4468 * StringUtils.getLevenshteinDistance("aaapppp", "") = 7
4469 * StringUtils.getLevenshteinDistance("frog", "fog") = 1
4470 * StringUtils.getLevenshteinDistance("fly", "ant") = 3
4471 * StringUtils.getLevenshteinDistance("elephant", "hippo") = 7
4472 * StringUtils.getLevenshteinDistance("hippo", "elephant") = 7
4473 * StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
4474 * StringUtils.getLevenshteinDistance("hello", "hallo") = 1
4475 * </pre>
4476 *
4477 * @param s the first String, must not be null
4478 * @param t the second String, must not be null
4479 * @return result distance
4480 * @throws IllegalArgumentException if either String input <code>null</code>
4481 */
4482 public static int getLevenshteinDistance(String s, String t) {
4483 if (s == null || t == null) {
4484 throw new IllegalArgumentException("Strings must not be null");
4485 }
4486 4911
4487 /* 4912 /*
4488 The difference between this impl. and the previous is that, rather 4913 The difference between this impl. and the previous is that, rather
4489 than creating and retaining a matrix of size s.length()+1 by t.length ()+1, 4914 than creating and retaining a matrix of size s.length()+1 by t.length ()+1,
4490 we maintain two single-dimensional arrays of length s.length()+1. Th e first, d, 4915 we maintain two single-dimensional arrays of length s.length()+1. Th e first, d,
4491 is the 'current working' distance array that maintains the newest dis tance cost 4916 is the 'current working' distance array that maintains the newest dis tance cost
4492 counts as we iterate through the characters of String s. Each time w e increment 4917 counts as we iterate through the characters of String s. Each time w e increment
4493 the index of String t we are comparing, d is copied to p, the second int[]. Doing so 4918 the index of String t we are comparing, d is copied to p, the second int[]. Doing so
4494 allows us to retain the previous cost counts as required by the algor ithm (taking 4919 allows us to retain the previous cost counts as required by the algor ithm (taking
4495 the minimum of the cost count to the left, up one, and diagonally up and to the left 4920 the minimum of the cost count to the left, up one, and diagonally up and to the left
4496 of the current cost count being calculated). (Note that the arrays a ren't really 4921 of the current cost count being calculated). (Note that the arrays a ren't really
4497 copied anymore, just switched...this is clearly much better than clon ing an array 4922 copied anymore, just switched...this is clearly much better than clon ing an array
4498 or doing a System.arraycopy() each time through the outer loop.) 4923 or doing a System.arraycopy() each time through the outer loop.)
4499 4924
4500 Effectively, the difference between the two implementations is this o ne does not 4925 Effectively, the difference between the two implementations is this o ne does not
4501 cause an out of memory condition when calculating the LD over two ver y large strings. 4926 cause an out of memory condition when calculating the LD over two ver y large strings.
4502 */ 4927 */
4503 4928
4504 int n = s.length(); // length of s 4929 int n = s.length(); // length of s
4505 int m = t.length(); // length of t 4930 int m = t.length(); // length of t
4506 4931
4507 if (n == 0) { 4932 if (n == 0)
4508 return m; 4933 {
4509 } else if (m == 0) { 4934 return m;
4510 return n; 4935 } else if (m == 0)
4511 } 4936 {
4512 4937 return n;
4513 if (n > m) {
4514 // swap the input strings to consume less memory
4515 String tmp = s;
4516 s = t;
4517 t = tmp;
4518 n = m;
4519 m = t.length();
4520 }
4521
4522 int p[] = new int[n+1]; //'previous' cost array, horizontally
4523 int d[] = new int[n+1]; // cost array, horizontally
4524 int _d[]; //placeholder to assist in swapping p and d
4525
4526 // indexes into strings s and t
4527 int i; // iterates through s
4528 int j; // iterates through t
4529
4530 char t_j; // jth character of t
4531
4532 int cost; // cost
4533
4534 for (i = 0; i<=n; i++) {
4535 p[i] = i;
4536 }
4537
4538 for (j = 1; j<=m; j++) {
4539 t_j = t.charAt(j-1);
4540 d[0] = j;
4541
4542 for (i=1; i<=n; i++) {
4543 cost = s.charAt(i-1)==t_j ? 0 : 1;
4544 // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
4545 d[i] = Math.min(Math.min(d[i-1]+1, p[i]+1), p[i-1]+cost);
4546 }
4547
4548 // copy current distance counts to 'previous row' distance counts
4549 _d = p;
4550 p = d;
4551 d = _d;
4552 }
4553
4554 // our last action in the above loop was to switch d and p, so p now
4555 // actually has the most recent cost counts
4556 return p[n];
4557 } 4938 }
4558 4939
4559 /** 4940 if (n > m)
4560 * <p>Gets the minimum of three <code>int</code> values.</p> 4941 {
4561 * 4942 // swap the input strings to consume less memory
4562 * @param a value 1 4943 String tmp = s;
4563 * @param b value 2 4944 s = t;
4564 * @param c value 3 4945 t = tmp;
4565 * @return the smallest of the values 4946 n = m;
4566 */ 4947 m = t.length();
4948 }
4949
4950 int p[] = new int[n + 1]; //'previous' cost array, horizontally
4951 int d[] = new int[n + 1]; // cost array, horizontally
4952 int _d[]; //placeholder to assist in swapping p and d
4953
4954 // indexes into strings s and t
4955 int i; // iterates through s
4956 int j; // iterates through t
4957
4958 char t_j; // jth character of t
4959
4960 int cost; // cost
4961
4962 for (i = 0; i <= n; i++)
4963 {
4964 p[i] = i;
4965 }
4966
4967 for (j = 1; j <= m; j++)
4968 {
4969 t_j = t.charAt(j - 1);
4970 d[0] = j;
4971
4972 for (i = 1; i <= n; i++)
4973 {
4974 cost = s.charAt(i - 1) == t_j ? 0 : 1;
4975 // minimum of cell to the left+1, to the top+1, diagonally left and up + cost
4976 d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost);
4977 }
4978
4979 // copy current distance counts to 'previous row' distance counts
4980 _d = p;
4981 p = d;
4982 d = _d;
4983 }
4984
4985 // our last action in the above loop was to switch d and p, so p now
4986 // actually has the most recent cost counts
4987 return p[n];
4988 }
4989
4990 /**
4991 * <p>Gets the minimum of three <code>int</code> values.</p>
4992 *
4993 * @param a value 1
4994 * @param b value 2
4995 * @param c value 3
4996 * @return the smallest of the values
4997 */
4567 /* 4998 /*
4568 private static int min(int a, int b, int c) { 4999 private static int min(int a, int b, int c) {
4569 // Method copied from NumberUtils to avoid dependency on subpackage 5000 // Method copied from NumberUtils to avoid dependency on subpackage
4570 if (b < a) { 5001 if (b < a) {
4571 a = b; 5002 a = b;
4572 } 5003 }
4573 if (c < a) { 5004 if (c < a) {
4574 a = c; 5005 a = c;
4575 } 5006 }
4576 return a; 5007 return a;
4577 } 5008 }
4578 */ 5009 */
4579 5010
4580 // startsWith 5011 // startsWith
4581 //----------------------------------------------------------------------- 5012 //-----------------------------------------------------------------------
4582 5013
4583 /** 5014 /**
4584 * <p>Check if a String starts with a specified prefix.</p> 5015 * <p>Check if a String starts with a specified prefix.</p>
4585 * 5016 * <p/>
4586 * <p><code>null</code>s are handled without exceptions. Two <code>null</cod e> 5017 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
4587 * references are considered to be equal. The comparison is case sensitive.< /p> 5018 * references are considered to be equal. The comparison is case sensitive.</p >
4588 * 5019 * <p/>
4589 * <pre> 5020 * <pre>
4590 * StringUtils.startsWith(null, null) = true 5021 * StringUtils.startsWith(null, null) = true
4591 * StringUtils.startsWith(null, "abcdef") = false 5022 * StringUtils.startsWith(null, "abcdef") = false
4592 * StringUtils.startsWith("abc", null) = false 5023 * StringUtils.startsWith("abc", null) = false
4593 * StringUtils.startsWith("abc", "abcdef") = true 5024 * StringUtils.startsWith("abc", "abcdef") = true
4594 * StringUtils.startsWith("abc", "ABCDEF") = false 5025 * StringUtils.startsWith("abc", "ABCDEF") = false
4595 * </pre> 5026 * </pre>
4596 * 5027 *
4597 * @see java.lang.String#startsWith(String) 5028 * @param str the String to check, may be null
4598 * @param str the String to check, may be null 5029 * @param prefix the prefix to find, may be null
4599 * @param prefix the prefix to find, may be null 5030 * @return <code>true</code> if the String starts with the prefix, case sensit ive, or
4600 * @return <code>true</code> if the String starts with the prefix, case sens itive, or 5031 * both <code>null</code>
4601 * both <code>null</code> 5032 * @see java.lang.String#startsWith(String)
4602 * @since 2.4 5033 * @since 2.4
4603 */ 5034 */
4604 public static boolean startsWith(String str, String prefix) { 5035 public static boolean startsWith(String str, String prefix)
4605 return startsWith(str, prefix, false); 5036 {
5037 return startsWith(str, prefix, false);
5038 }
5039
5040 /**
5041 * <p>Case insensitive check if a String starts with a specified prefix.</p>
5042 * <p/>
5043 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
5044 * references are considered to be equal. The comparison is case insensitive.< /p>
5045 * <p/>
5046 * <pre>
5047 * StringUtils.startsWithIgnoreCase(null, null) = true
5048 * StringUtils.startsWithIgnoreCase(null, "abcdef") = false
5049 * StringUtils.startsWithIgnoreCase("abc", null) = false
5050 * StringUtils.startsWithIgnoreCase("abc", "abcdef") = true
5051 * StringUtils.startsWithIgnoreCase("abc", "ABCDEF") = true
5052 * </pre>
5053 *
5054 * @param str the String to check, may be null
5055 * @param prefix the prefix to find, may be null
5056 * @return <code>true</code> if the String starts with the prefix, case insens itive, or
5057 * both <code>null</code>
5058 * @see java.lang.String#startsWith(String)
5059 * @since 2.4
5060 */
5061 public static boolean startsWithIgnoreCase(String str, String prefix)
5062 {
5063 return startsWith(str, prefix, true);
5064 }
5065
5066 /**
5067 * <p>Check if a String starts with a specified prefix (optionally case insens itive).</p>
5068 *
5069 * @param str the String to check, may be null
5070 * @param prefix the prefix to find, may be null
5071 * @param ignoreCase inidicates whether the compare should ignore case
5072 * (case insensitive) or not.
5073 * @return <code>true</code> if the String starts with the prefix or
5074 * both <code>null</code>
5075 * @see java.lang.String#startsWith(String)
5076 */
5077 private static boolean startsWith(String str, String prefix, boolean ignoreCas e)
5078 {
5079 if (str == null || prefix == null)
5080 {
5081 return (str == null && prefix == null);
4606 } 5082 }
5083 if (prefix.length() > str.length())
5084 {
5085 return false;
5086 }
5087 return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length());
5088 }
4607 5089
4608 /** 5090 // endsWith
4609 * <p>Case insensitive check if a String starts with a specified prefix.</p> 5091 //-----------------------------------------------------------------------
4610 * 5092
4611 * <p><code>null</code>s are handled without exceptions. Two <code>null</cod e> 5093 /**
4612 * references are considered to be equal. The comparison is case insensitive .</p> 5094 * <p>Check if a String ends with a specified suffix.</p>
4613 * 5095 * <p/>
4614 * <pre> 5096 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
4615 * StringUtils.startsWithIgnoreCase(null, null) = true 5097 * references are considered to be equal. The comparison is case sensitive.</p >
4616 * StringUtils.startsWithIgnoreCase(null, "abcdef") = false 5098 * <p/>
4617 * StringUtils.startsWithIgnoreCase("abc", null) = false 5099 * <pre>
4618 * StringUtils.startsWithIgnoreCase("abc", "abcdef") = true 5100 * StringUtils.endsWith(null, null) = true
4619 * StringUtils.startsWithIgnoreCase("abc", "ABCDEF") = true 5101 * StringUtils.endsWith(null, "abcdef") = false
4620 * </pre> 5102 * StringUtils.endsWith("def", null) = false
4621 * 5103 * StringUtils.endsWith("def", "abcdef") = true
4622 * @see java.lang.String#startsWith(String) 5104 * StringUtils.endsWith("def", "ABCDEF") = false
4623 * @param str the String to check, may be null 5105 * </pre>
4624 * @param prefix the prefix to find, may be null 5106 *
4625 * @return <code>true</code> if the String starts with the prefix, case inse nsitive, or 5107 * @param str the String to check, may be null
4626 * both <code>null</code> 5108 * @param suffix the suffix to find, may be null
4627 * @since 2.4 5109 * @return <code>true</code> if the String ends with the suffix, case sensitiv e, or
4628 */ 5110 * both <code>null</code>
4629 public static boolean startsWithIgnoreCase(String str, String prefix) { 5111 * @see java.lang.String#endsWith(String)
4630 return startsWith(str, prefix, true); 5112 * @since 2.4
5113 */
5114 public static boolean endsWith(String str, String suffix)
5115 {
5116 return endsWith(str, suffix, false);
5117 }
5118
5119 /**
5120 * <p>Case insensitive check if a String ends with a specified suffix.</p>
5121 * <p/>
5122 * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
5123 * references are considered to be equal. The comparison is case insensitive.< /p>
5124 * <p/>
5125 * <pre>
5126 * StringUtils.endsWithIgnoreCase(null, null) = true
5127 * StringUtils.endsWithIgnoreCase(null, "abcdef") = false
5128 * StringUtils.endsWithIgnoreCase("def", null) = false
5129 * StringUtils.endsWithIgnoreCase("def", "abcdef") = true
5130 * StringUtils.endsWithIgnoreCase("def", "ABCDEF") = false
5131 * </pre>
5132 *
5133 * @param str the String to check, may be null
5134 * @param suffix the suffix to find, may be null
5135 * @return <code>true</code> if the String ends with the suffix, case insensit ive, or
5136 * both <code>null</code>
5137 * @see java.lang.String#endsWith(String)
5138 * @since 2.4
5139 */
5140 public static boolean endsWithIgnoreCase(String str, String suffix)
5141 {
5142 return endsWith(str, suffix, true);
5143 }
5144
5145 /**
5146 * <p>Check if a String ends with a specified suffix (optionally case insensit ive).</p>
5147 *
5148 * @param str the String to check, may be null
5149 * @param suffix the suffix to find, may be null
5150 * @param ignoreCase inidicates whether the compare should ignore case
5151 * (case insensitive) or not.
5152 * @return <code>true</code> if the String starts with the prefix or
5153 * both <code>null</code>
5154 * @see java.lang.String#endsWith(String)
5155 */
5156 private static boolean endsWith(String str, String suffix, boolean ignoreCase)
5157 {
5158 if (str == null || suffix == null)
5159 {
5160 return (str == null && suffix == null);
4631 } 5161 }
4632 5162 if (suffix.length() > str.length())
4633 /** 5163 {
4634 * <p>Check if a String starts with a specified prefix (optionally case inse nsitive).</p> 5164 return false;
4635 *
4636 * @see java.lang.String#startsWith(String)
4637 * @param str the String to check, may be null
4638 * @param prefix the prefix to find, may be null
4639 * @param ignoreCase inidicates whether the compare should ignore case
4640 * (case insensitive) or not.
4641 * @return <code>true</code> if the String starts with the prefix or
4642 * both <code>null</code>
4643 */
4644 private static boolean startsWith(String str, String prefix, boolean ignoreC ase) {
4645 if (str == null || prefix == null) {
4646 return (str == null && prefix == null);
4647 }
4648 if (prefix.length() > str.length()) {
4649 return false;
4650 }
4651 return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length());
4652 } 5165 }
4653 5166 int strOffset = str.length() - suffix.length();
4654 // endsWith 5167 return str.regionMatches(ignoreCase, strOffset, suffix, 0, suffix.length());
4655 //----------------------------------------------------------------------- 5168 }
4656
4657 /**
4658 * <p>Check if a String ends with a specified suffix.</p>
4659 *
4660 * <p><code>null</code>s are handled without exceptions. Two <code>null</cod e>
4661 * references are considered to be equal. The comparison is case sensitive.< /p>
4662 *
4663 * <pre>
4664 * StringUtils.endsWith(null, null) = true
4665 * StringUtils.endsWith(null, "abcdef") = false
4666 * StringUtils.endsWith("def", null) = false
4667 * StringUtils.endsWith("def", "abcdef") = true
4668 * StringUtils.endsWith("def", "ABCDEF") = false
4669 * </pre>
4670 *
4671 * @see java.lang.String#endsWith(String)
4672 * @param str the String to check, may be null
4673 * @param suffix the suffix to find, may be null
4674 * @return <code>true</code> if the String ends with the suffix, case sensit ive, or
4675 * both <code>null</code>
4676 * @since 2.4
4677 */
4678 public static boolean endsWith(String str, String suffix) {
4679 return endsWith(str, suffix, false);
4680 }
4681
4682 /**
4683 * <p>Case insensitive check if a String ends with a specified suffix.</p>
4684 *
4685 * <p><code>null</code>s are handled without exceptions. Two <code>null</cod e>
4686 * references are considered to be equal. The comparison is case insensitive .</p>
4687 *
4688 * <pre>
4689 * StringUtils.endsWithIgnoreCase(null, null) = true
4690 * StringUtils.endsWithIgnoreCase(null, "abcdef") = false
4691 * StringUtils.endsWithIgnoreCase("def", null) = false
4692 * StringUtils.endsWithIgnoreCase("def", "abcdef") = true
4693 * StringUtils.endsWithIgnoreCase("def", "ABCDEF") = false
4694 * </pre>
4695 *
4696 * @see java.lang.String#endsWith(String)
4697 * @param str the String to check, may be null
4698 * @param suffix the suffix to find, may be null
4699 * @return <code>true</code> if the String ends with the suffix, case insens itive, or
4700 * both <code>null</code>
4701 * @since 2.4
4702 */
4703 public static boolean endsWithIgnoreCase(String str, String suffix) {
4704 return endsWith(str, suffix, true);
4705 }
4706
4707 /**
4708 * <p>Check if a String ends with a specified suffix (optionally case insens itive).</p>
4709 *
4710 * @see java.lang.String#endsWith(String)
4711 * @param str the String to check, may be null
4712 * @param suffix the suffix to find, may be null
4713 * @param ignoreCase inidicates whether the compare should ignore case
4714 * (case insensitive) or not.
4715 * @return <code>true</code> if the String starts with the prefix or
4716 * both <code>null</code>
4717 */
4718 private static boolean endsWith(String str, String suffix, boolean ignoreCas e) {
4719 if (str == null || suffix == null) {
4720 return (str == null && suffix == null);
4721 }
4722 if (suffix.length() > str.length()) {
4723 return false;
4724 }
4725 int strOffset = str.length() - suffix.length();
4726 return str.regionMatches(ignoreCase, strOffset, suffix, 0, suffix.length ());
4727 }
4728 5169
4729 } 5170 }
OLDNEW

Powered by Google App Engine
This is Rietveld