001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.lang3;
018
019 /**
020 * <p>Operations on char primitives and Character objects.</p>
021 *
022 * <p>This class tries to handle {@code null} input gracefully.
023 * An exception will not be thrown for a {@code null} input.
024 * Each method documents its behaviour in more detail.</p>
025 *
026 * <p>#ThreadSafe#</p>
027 * @since 2.1
028 * @version $Id: CharUtils.java 1158279 2011-08-16 14:06:45Z ggregory $
029 */
030 public class CharUtils {
031
032 private static final String[] CHAR_STRING_ARRAY = new String[128];
033
034 /**
035 * {@code \u000a} linefeed LF ('\n').
036 *
037 * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
038 * for Character and String Literals</a>
039 * @since 2.2
040 */
041 public static final char LF = '\n';
042
043 /**
044 * {@code \u000d} carriage return CR ('\r').
045 *
046 * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
047 * for Character and String Literals</a>
048 * @since 2.2
049 */
050 public static final char CR = '\r';
051
052
053 static {
054 for (char c = 0; c < CHAR_STRING_ARRAY.length; c++) {
055 CHAR_STRING_ARRAY[c] = String.valueOf(c);
056 }
057 }
058
059 /**
060 * <p>{@code CharUtils} instances should NOT be constructed in standard programming.
061 * Instead, the class should be used as {@code CharUtils.toString('c');}.</p>
062 *
063 * <p>This constructor is public to permit tools that require a JavaBean instance
064 * to operate.</p>
065 */
066 public CharUtils() {
067 super();
068 }
069
070 //-----------------------------------------------------------------------
071 /**
072 * <p>Converts the character to a Character.</p>
073 *
074 * <p>For ASCII 7 bit characters, this uses a cache that will return the
075 * same Character object each time.</p>
076 *
077 * <pre>
078 * CharUtils.toCharacterObject(' ') = ' '
079 * CharUtils.toCharacterObject('A') = 'A'
080 * </pre>
081 *
082 * @deprecated Java 5 introduced {@link Character#valueOf(char)} which caches chars 0 through 127.
083 * @param ch the character to convert
084 * @return a Character of the specified character
085 */
086 @Deprecated
087 public static Character toCharacterObject(char ch) {
088 return Character.valueOf(ch);
089 }
090
091 /**
092 * <p>Converts the String to a Character using the first character, returning
093 * null for empty Strings.</p>
094 *
095 * <p>For ASCII 7 bit characters, this uses a cache that will return the
096 * same Character object each time.</p>
097 *
098 * <pre>
099 * CharUtils.toCharacterObject(null) = null
100 * CharUtils.toCharacterObject("") = null
101 * CharUtils.toCharacterObject("A") = 'A'
102 * CharUtils.toCharacterObject("BA") = 'B'
103 * </pre>
104 *
105 * @param str the character to convert
106 * @return the Character value of the first letter of the String
107 */
108 public static Character toCharacterObject(String str) {
109 if (StringUtils.isEmpty(str)) {
110 return null;
111 }
112 return Character.valueOf(str.charAt(0));
113 }
114
115 //-----------------------------------------------------------------------
116 /**
117 * <p>Converts the Character to a char throwing an exception for {@code null}.</p>
118 *
119 * <pre>
120 * CharUtils.toChar(' ') = ' '
121 * CharUtils.toChar('A') = 'A'
122 * CharUtils.toChar(null) throws IllegalArgumentException
123 * </pre>
124 *
125 * @param ch the character to convert
126 * @return the char value of the Character
127 * @throws IllegalArgumentException if the Character is null
128 */
129 public static char toChar(Character ch) {
130 if (ch == null) {
131 throw new IllegalArgumentException("The Character must not be null");
132 }
133 return ch.charValue();
134 }
135
136 /**
137 * <p>Converts the Character to a char handling {@code null}.</p>
138 *
139 * <pre>
140 * CharUtils.toChar(null, 'X') = 'X'
141 * CharUtils.toChar(' ', 'X') = ' '
142 * CharUtils.toChar('A', 'X') = 'A'
143 * </pre>
144 *
145 * @param ch the character to convert
146 * @param defaultValue the value to use if the Character is null
147 * @return the char value of the Character or the default if null
148 */
149 public static char toChar(Character ch, char defaultValue) {
150 if (ch == null) {
151 return defaultValue;
152 }
153 return ch.charValue();
154 }
155
156 //-----------------------------------------------------------------------
157 /**
158 * <p>Converts the String to a char using the first character, throwing
159 * an exception on empty Strings.</p>
160 *
161 * <pre>
162 * CharUtils.toChar("A") = 'A'
163 * CharUtils.toChar("BA") = 'B'
164 * CharUtils.toChar(null) throws IllegalArgumentException
165 * CharUtils.toChar("") throws IllegalArgumentException
166 * </pre>
167 *
168 * @param str the character to convert
169 * @return the char value of the first letter of the String
170 * @throws IllegalArgumentException if the String is empty
171 */
172 public static char toChar(String str) {
173 if (StringUtils.isEmpty(str)) {
174 throw new IllegalArgumentException("The String must not be empty");
175 }
176 return str.charAt(0);
177 }
178
179 /**
180 * <p>Converts the String to a char using the first character, defaulting
181 * the value on empty Strings.</p>
182 *
183 * <pre>
184 * CharUtils.toChar(null, 'X') = 'X'
185 * CharUtils.toChar("", 'X') = 'X'
186 * CharUtils.toChar("A", 'X') = 'A'
187 * CharUtils.toChar("BA", 'X') = 'B'
188 * </pre>
189 *
190 * @param str the character to convert
191 * @param defaultValue the value to use if the Character is null
192 * @return the char value of the first letter of the String or the default if null
193 */
194 public static char toChar(String str, char defaultValue) {
195 if (StringUtils.isEmpty(str)) {
196 return defaultValue;
197 }
198 return str.charAt(0);
199 }
200
201 //-----------------------------------------------------------------------
202 /**
203 * <p>Converts the character to the Integer it represents, throwing an
204 * exception if the character is not numeric.</p>
205 *
206 * <p>This method coverts the char '1' to the int 1 and so on.</p>
207 *
208 * <pre>
209 * CharUtils.toIntValue('3') = 3
210 * CharUtils.toIntValue('A') throws IllegalArgumentException
211 * </pre>
212 *
213 * @param ch the character to convert
214 * @return the int value of the character
215 * @throws IllegalArgumentException if the character is not ASCII numeric
216 */
217 public static int toIntValue(char ch) {
218 if (isAsciiNumeric(ch) == false) {
219 throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'");
220 }
221 return ch - 48;
222 }
223
224 /**
225 * <p>Converts the character to the Integer it represents, throwing an
226 * exception if the character is not numeric.</p>
227 *
228 * <p>This method coverts the char '1' to the int 1 and so on.</p>
229 *
230 * <pre>
231 * CharUtils.toIntValue('3', -1) = 3
232 * CharUtils.toIntValue('A', -1) = -1
233 * </pre>
234 *
235 * @param ch the character to convert
236 * @param defaultValue the default value to use if the character is not numeric
237 * @return the int value of the character
238 */
239 public static int toIntValue(char ch, int defaultValue) {
240 if (isAsciiNumeric(ch) == false) {
241 return defaultValue;
242 }
243 return ch - 48;
244 }
245
246 /**
247 * <p>Converts the character to the Integer it represents, throwing an
248 * exception if the character is not numeric.</p>
249 *
250 * <p>This method coverts the char '1' to the int 1 and so on.</p>
251 *
252 * <pre>
253 * CharUtils.toIntValue('3') = 3
254 * CharUtils.toIntValue(null) throws IllegalArgumentException
255 * CharUtils.toIntValue('A') throws IllegalArgumentException
256 * </pre>
257 *
258 * @param ch the character to convert, not null
259 * @return the int value of the character
260 * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
261 */
262 public static int toIntValue(Character ch) {
263 if (ch == null) {
264 throw new IllegalArgumentException("The character must not be null");
265 }
266 return toIntValue(ch.charValue());
267 }
268
269 /**
270 * <p>Converts the character to the Integer it represents, throwing an
271 * exception if the character is not numeric.</p>
272 *
273 * <p>This method coverts the char '1' to the int 1 and so on.</p>
274 *
275 * <pre>
276 * CharUtils.toIntValue(null, -1) = -1
277 * CharUtils.toIntValue('3', -1) = 3
278 * CharUtils.toIntValue('A', -1) = -1
279 * </pre>
280 *
281 * @param ch the character to convert
282 * @param defaultValue the default value to use if the character is not numeric
283 * @return the int value of the character
284 */
285 public static int toIntValue(Character ch, int defaultValue) {
286 if (ch == null) {
287 return defaultValue;
288 }
289 return toIntValue(ch.charValue(), defaultValue);
290 }
291
292 //-----------------------------------------------------------------------
293 /**
294 * <p>Converts the character to a String that contains the one character.</p>
295 *
296 * <p>For ASCII 7 bit characters, this uses a cache that will return the
297 * same String object each time.</p>
298 *
299 * <pre>
300 * CharUtils.toString(' ') = " "
301 * CharUtils.toString('A') = "A"
302 * </pre>
303 *
304 * @param ch the character to convert
305 * @return a String containing the one specified character
306 */
307 public static String toString(char ch) {
308 if (ch < 128) {
309 return CHAR_STRING_ARRAY[ch];
310 }
311 return new String(new char[] {ch});
312 }
313
314 /**
315 * <p>Converts the character to a String that contains the one character.</p>
316 *
317 * <p>For ASCII 7 bit characters, this uses a cache that will return the
318 * same String object each time.</p>
319 *
320 * <p>If {@code null} is passed in, {@code null} will be returned.</p>
321 *
322 * <pre>
323 * CharUtils.toString(null) = null
324 * CharUtils.toString(' ') = " "
325 * CharUtils.toString('A') = "A"
326 * </pre>
327 *
328 * @param ch the character to convert
329 * @return a String containing the one specified character
330 */
331 public static String toString(Character ch) {
332 if (ch == null) {
333 return null;
334 }
335 return toString(ch.charValue());
336 }
337
338 //--------------------------------------------------------------------------
339 /**
340 * <p>Converts the string to the Unicode format '\u0020'.</p>
341 *
342 * <p>This format is the Java source code format.</p>
343 *
344 * <pre>
345 * CharUtils.unicodeEscaped(' ') = "\u0020"
346 * CharUtils.unicodeEscaped('A') = "\u0041"
347 * </pre>
348 *
349 * @param ch the character to convert
350 * @return the escaped Unicode string
351 */
352 public static String unicodeEscaped(char ch) {
353 if (ch < 0x10) {
354 return "\\u000" + Integer.toHexString(ch);
355 } else if (ch < 0x100) {
356 return "\\u00" + Integer.toHexString(ch);
357 } else if (ch < 0x1000) {
358 return "\\u0" + Integer.toHexString(ch);
359 }
360 return "\\u" + Integer.toHexString(ch);
361 }
362
363 /**
364 * <p>Converts the string to the Unicode format '\u0020'.</p>
365 *
366 * <p>This format is the Java source code format.</p>
367 *
368 * <p>If {@code null} is passed in, {@code null} will be returned.</p>
369 *
370 * <pre>
371 * CharUtils.unicodeEscaped(null) = null
372 * CharUtils.unicodeEscaped(' ') = "\u0020"
373 * CharUtils.unicodeEscaped('A') = "\u0041"
374 * </pre>
375 *
376 * @param ch the character to convert, may be null
377 * @return the escaped Unicode string, null if null input
378 */
379 public static String unicodeEscaped(Character ch) {
380 if (ch == null) {
381 return null;
382 }
383 return unicodeEscaped(ch.charValue());
384 }
385
386 //--------------------------------------------------------------------------
387 /**
388 * <p>Checks whether the character is ASCII 7 bit.</p>
389 *
390 * <pre>
391 * CharUtils.isAscii('a') = true
392 * CharUtils.isAscii('A') = true
393 * CharUtils.isAscii('3') = true
394 * CharUtils.isAscii('-') = true
395 * CharUtils.isAscii('\n') = true
396 * CharUtils.isAscii('©') = false
397 * </pre>
398 *
399 * @param ch the character to check
400 * @return true if less than 128
401 */
402 public static boolean isAscii(char ch) {
403 return ch < 128;
404 }
405
406 /**
407 * <p>Checks whether the character is ASCII 7 bit printable.</p>
408 *
409 * <pre>
410 * CharUtils.isAsciiPrintable('a') = true
411 * CharUtils.isAsciiPrintable('A') = true
412 * CharUtils.isAsciiPrintable('3') = true
413 * CharUtils.isAsciiPrintable('-') = true
414 * CharUtils.isAsciiPrintable('\n') = false
415 * CharUtils.isAsciiPrintable('©') = false
416 * </pre>
417 *
418 * @param ch the character to check
419 * @return true if between 32 and 126 inclusive
420 */
421 public static boolean isAsciiPrintable(char ch) {
422 return ch >= 32 && ch < 127;
423 }
424
425 /**
426 * <p>Checks whether the character is ASCII 7 bit control.</p>
427 *
428 * <pre>
429 * CharUtils.isAsciiControl('a') = false
430 * CharUtils.isAsciiControl('A') = false
431 * CharUtils.isAsciiControl('3') = false
432 * CharUtils.isAsciiControl('-') = false
433 * CharUtils.isAsciiControl('\n') = true
434 * CharUtils.isAsciiControl('©') = false
435 * </pre>
436 *
437 * @param ch the character to check
438 * @return true if less than 32 or equals 127
439 */
440 public static boolean isAsciiControl(char ch) {
441 return ch < 32 || ch == 127;
442 }
443
444 /**
445 * <p>Checks whether the character is ASCII 7 bit alphabetic.</p>
446 *
447 * <pre>
448 * CharUtils.isAsciiAlpha('a') = true
449 * CharUtils.isAsciiAlpha('A') = true
450 * CharUtils.isAsciiAlpha('3') = false
451 * CharUtils.isAsciiAlpha('-') = false
452 * CharUtils.isAsciiAlpha('\n') = false
453 * CharUtils.isAsciiAlpha('©') = false
454 * </pre>
455 *
456 * @param ch the character to check
457 * @return true if between 65 and 90 or 97 and 122 inclusive
458 */
459 public static boolean isAsciiAlpha(char ch) {
460 return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
461 }
462
463 /**
464 * <p>Checks whether the character is ASCII 7 bit alphabetic upper case.</p>
465 *
466 * <pre>
467 * CharUtils.isAsciiAlphaUpper('a') = false
468 * CharUtils.isAsciiAlphaUpper('A') = true
469 * CharUtils.isAsciiAlphaUpper('3') = false
470 * CharUtils.isAsciiAlphaUpper('-') = false
471 * CharUtils.isAsciiAlphaUpper('\n') = false
472 * CharUtils.isAsciiAlphaUpper('©') = false
473 * </pre>
474 *
475 * @param ch the character to check
476 * @return true if between 65 and 90 inclusive
477 */
478 public static boolean isAsciiAlphaUpper(char ch) {
479 return ch >= 'A' && ch <= 'Z';
480 }
481
482 /**
483 * <p>Checks whether the character is ASCII 7 bit alphabetic lower case.</p>
484 *
485 * <pre>
486 * CharUtils.isAsciiAlphaLower('a') = true
487 * CharUtils.isAsciiAlphaLower('A') = false
488 * CharUtils.isAsciiAlphaLower('3') = false
489 * CharUtils.isAsciiAlphaLower('-') = false
490 * CharUtils.isAsciiAlphaLower('\n') = false
491 * CharUtils.isAsciiAlphaLower('©') = false
492 * </pre>
493 *
494 * @param ch the character to check
495 * @return true if between 97 and 122 inclusive
496 */
497 public static boolean isAsciiAlphaLower(char ch) {
498 return ch >= 'a' && ch <= 'z';
499 }
500
501 /**
502 * <p>Checks whether the character is ASCII 7 bit numeric.</p>
503 *
504 * <pre>
505 * CharUtils.isAsciiNumeric('a') = false
506 * CharUtils.isAsciiNumeric('A') = false
507 * CharUtils.isAsciiNumeric('3') = true
508 * CharUtils.isAsciiNumeric('-') = false
509 * CharUtils.isAsciiNumeric('\n') = false
510 * CharUtils.isAsciiNumeric('©') = false
511 * </pre>
512 *
513 * @param ch the character to check
514 * @return true if between 48 and 57 inclusive
515 */
516 public static boolean isAsciiNumeric(char ch) {
517 return ch >= '0' && ch <= '9';
518 }
519
520 /**
521 * <p>Checks whether the character is ASCII 7 bit numeric.</p>
522 *
523 * <pre>
524 * CharUtils.isAsciiAlphanumeric('a') = true
525 * CharUtils.isAsciiAlphanumeric('A') = true
526 * CharUtils.isAsciiAlphanumeric('3') = true
527 * CharUtils.isAsciiAlphanumeric('-') = false
528 * CharUtils.isAsciiAlphanumeric('\n') = false
529 * CharUtils.isAsciiAlphanumeric('©') = false
530 * </pre>
531 *
532 * @param ch the character to check
533 * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
534 */
535 public static boolean isAsciiAlphanumeric(char ch) {
536 return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9');
537 }
538
539 }