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 1153229 2011-08-02 18:04:51Z ggregory $
029 */
030 public class CharUtils {
031
032 private static final String CHAR_STRING =
033 "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007" +
034 "\b\t\n\u000b\f\r\u000e\u000f" +
035 "\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017" +
036 "\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f" +
037 "\u0020\u0021\"\u0023\u0024\u0025\u0026\u0027" +
038 "\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f" +
039 "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037" +
040 "\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f" +
041 "\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047" +
042 "\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f" +
043 "\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057" +
044 "\u0058\u0059\u005a\u005b\\\u005d\u005e\u005f" +
045 "\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067" +
046 "\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f" +
047 "\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077" +
048 "\u0078\u0079\u007a\u007b\u007c\u007d\u007e\u007f";
049
050 private static final String[] CHAR_STRING_ARRAY = new String[128];
051
052 /**
053 * {@code \u000a} linefeed LF ('\n').
054 *
055 * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
056 * for Character and String Literals</a>
057 * @since 2.2
058 */
059 public static final char LF = '\n';
060
061 /**
062 * {@code \u000d} carriage return CR ('\r').
063 *
064 * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
065 * for Character and String Literals</a>
066 * @since 2.2
067 */
068 public static final char CR = '\r';
069
070
071 static {
072 for (int i = 127; i >= 0; i--) {
073 CHAR_STRING_ARRAY[i] = CHAR_STRING.substring(i, i + 1);
074 }
075 }
076
077 /**
078 * <p>{@code CharUtils} instances should NOT be constructed in standard programming.
079 * Instead, the class should be used as {@code CharUtils.toString('c');}.</p>
080 *
081 * <p>This constructor is public to permit tools that require a JavaBean instance
082 * to operate.</p>
083 */
084 public CharUtils() {
085 super();
086 }
087
088 //-----------------------------------------------------------------------
089 /**
090 * <p>Converts the character to a Character.</p>
091 *
092 * <p>For ASCII 7 bit characters, this uses a cache that will return the
093 * same Character object each time.</p>
094 *
095 * <pre>
096 * CharUtils.toCharacterObject(' ') = ' '
097 * CharUtils.toCharacterObject('A') = 'A'
098 * </pre>
099 *
100 * @deprecated Java 5 introduced {@link Character#valueOf(char)} which caches chars 0 through 127.
101 * @param ch the character to convert
102 * @return a Character of the specified character
103 */
104 @Deprecated
105 public static Character toCharacterObject(char ch) {
106 return Character.valueOf(ch);
107 }
108
109 /**
110 * <p>Converts the String to a Character using the first character, returning
111 * null for empty Strings.</p>
112 *
113 * <p>For ASCII 7 bit characters, this uses a cache that will return the
114 * same Character object each time.</p>
115 *
116 * <pre>
117 * CharUtils.toCharacterObject(null) = null
118 * CharUtils.toCharacterObject("") = null
119 * CharUtils.toCharacterObject("A") = 'A'
120 * CharUtils.toCharacterObject("BA") = 'B'
121 * </pre>
122 *
123 * @param str the character to convert
124 * @return the Character value of the first letter of the String
125 */
126 public static Character toCharacterObject(String str) {
127 if (StringUtils.isEmpty(str)) {
128 return null;
129 }
130 return Character.valueOf(str.charAt(0));
131 }
132
133 //-----------------------------------------------------------------------
134 /**
135 * <p>Converts the Character to a char throwing an exception for {@code null}.</p>
136 *
137 * <pre>
138 * CharUtils.toChar(' ') = ' '
139 * CharUtils.toChar('A') = 'A'
140 * CharUtils.toChar(null) throws IllegalArgumentException
141 * </pre>
142 *
143 * @param ch the character to convert
144 * @return the char value of the Character
145 * @throws IllegalArgumentException if the Character is null
146 */
147 public static char toChar(Character ch) {
148 if (ch == null) {
149 throw new IllegalArgumentException("The Character must not be null");
150 }
151 return ch.charValue();
152 }
153
154 /**
155 * <p>Converts the Character to a char handling {@code null}.</p>
156 *
157 * <pre>
158 * CharUtils.toChar(null, 'X') = 'X'
159 * CharUtils.toChar(' ', 'X') = ' '
160 * CharUtils.toChar('A', 'X') = 'A'
161 * </pre>
162 *
163 * @param ch the character to convert
164 * @param defaultValue the value to use if the Character is null
165 * @return the char value of the Character or the default if null
166 */
167 public static char toChar(Character ch, char defaultValue) {
168 if (ch == null) {
169 return defaultValue;
170 }
171 return ch.charValue();
172 }
173
174 //-----------------------------------------------------------------------
175 /**
176 * <p>Converts the String to a char using the first character, throwing
177 * an exception on empty Strings.</p>
178 *
179 * <pre>
180 * CharUtils.toChar("A") = 'A'
181 * CharUtils.toChar("BA") = 'B'
182 * CharUtils.toChar(null) throws IllegalArgumentException
183 * CharUtils.toChar("") throws IllegalArgumentException
184 * </pre>
185 *
186 * @param str the character to convert
187 * @return the char value of the first letter of the String
188 * @throws IllegalArgumentException if the String is empty
189 */
190 public static char toChar(String str) {
191 if (StringUtils.isEmpty(str)) {
192 throw new IllegalArgumentException("The String must not be empty");
193 }
194 return str.charAt(0);
195 }
196
197 /**
198 * <p>Converts the String to a char using the first character, defaulting
199 * the value on empty Strings.</p>
200 *
201 * <pre>
202 * CharUtils.toChar(null, 'X') = 'X'
203 * CharUtils.toChar("", 'X') = 'X'
204 * CharUtils.toChar("A", 'X') = 'A'
205 * CharUtils.toChar("BA", 'X') = 'B'
206 * </pre>
207 *
208 * @param str the character to convert
209 * @param defaultValue the value to use if the Character is null
210 * @return the char value of the first letter of the String or the default if null
211 */
212 public static char toChar(String str, char defaultValue) {
213 if (StringUtils.isEmpty(str)) {
214 return defaultValue;
215 }
216 return str.charAt(0);
217 }
218
219 //-----------------------------------------------------------------------
220 /**
221 * <p>Converts the character to the Integer it represents, throwing an
222 * exception if the character is not numeric.</p>
223 *
224 * <p>This method coverts the char '1' to the int 1 and so on.</p>
225 *
226 * <pre>
227 * CharUtils.toIntValue('3') = 3
228 * CharUtils.toIntValue('A') throws IllegalArgumentException
229 * </pre>
230 *
231 * @param ch the character to convert
232 * @return the int value of the character
233 * @throws IllegalArgumentException if the character is not ASCII numeric
234 */
235 public static int toIntValue(char ch) {
236 if (isAsciiNumeric(ch) == false) {
237 throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'");
238 }
239 return ch - 48;
240 }
241
242 /**
243 * <p>Converts the character to the Integer it represents, throwing an
244 * exception if the character is not numeric.</p>
245 *
246 * <p>This method coverts the char '1' to the int 1 and so on.</p>
247 *
248 * <pre>
249 * CharUtils.toIntValue('3', -1) = 3
250 * CharUtils.toIntValue('A', -1) = -1
251 * </pre>
252 *
253 * @param ch the character to convert
254 * @param defaultValue the default value to use if the character is not numeric
255 * @return the int value of the character
256 */
257 public static int toIntValue(char ch, int defaultValue) {
258 if (isAsciiNumeric(ch) == false) {
259 return defaultValue;
260 }
261 return ch - 48;
262 }
263
264 /**
265 * <p>Converts the character to the Integer it represents, throwing an
266 * exception if the character is not numeric.</p>
267 *
268 * <p>This method coverts the char '1' to the int 1 and so on.</p>
269 *
270 * <pre>
271 * CharUtils.toIntValue('3') = 3
272 * CharUtils.toIntValue(null) throws IllegalArgumentException
273 * CharUtils.toIntValue('A') throws IllegalArgumentException
274 * </pre>
275 *
276 * @param ch the character to convert, not null
277 * @return the int value of the character
278 * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
279 */
280 public static int toIntValue(Character ch) {
281 if (ch == null) {
282 throw new IllegalArgumentException("The character must not be null");
283 }
284 return toIntValue(ch.charValue());
285 }
286
287 /**
288 * <p>Converts the character to the Integer it represents, throwing an
289 * exception if the character is not numeric.</p>
290 *
291 * <p>This method coverts the char '1' to the int 1 and so on.</p>
292 *
293 * <pre>
294 * CharUtils.toIntValue(null, -1) = -1
295 * CharUtils.toIntValue('3', -1) = 3
296 * CharUtils.toIntValue('A', -1) = -1
297 * </pre>
298 *
299 * @param ch the character to convert
300 * @param defaultValue the default value to use if the character is not numeric
301 * @return the int value of the character
302 */
303 public static int toIntValue(Character ch, int defaultValue) {
304 if (ch == null) {
305 return defaultValue;
306 }
307 return toIntValue(ch.charValue(), defaultValue);
308 }
309
310 //-----------------------------------------------------------------------
311 /**
312 * <p>Converts the character to a String that contains the one character.</p>
313 *
314 * <p>For ASCII 7 bit characters, this uses a cache that will return the
315 * same String object each time.</p>
316 *
317 * <pre>
318 * CharUtils.toString(' ') = " "
319 * CharUtils.toString('A') = "A"
320 * </pre>
321 *
322 * @param ch the character to convert
323 * @return a String containing the one specified character
324 */
325 public static String toString(char ch) {
326 if (ch < 128) {
327 return CHAR_STRING_ARRAY[ch];
328 }
329 return new String(new char[] {ch});
330 }
331
332 /**
333 * <p>Converts the character to a String that contains the one character.</p>
334 *
335 * <p>For ASCII 7 bit characters, this uses a cache that will return the
336 * same String object each time.</p>
337 *
338 * <p>If {@code null} is passed in, {@code null} will be returned.</p>
339 *
340 * <pre>
341 * CharUtils.toString(null) = null
342 * CharUtils.toString(' ') = " "
343 * CharUtils.toString('A') = "A"
344 * </pre>
345 *
346 * @param ch the character to convert
347 * @return a String containing the one specified character
348 */
349 public static String toString(Character ch) {
350 if (ch == null) {
351 return null;
352 }
353 return toString(ch.charValue());
354 }
355
356 //--------------------------------------------------------------------------
357 /**
358 * <p>Converts the string to the Unicode format '\u0020'.</p>
359 *
360 * <p>This format is the Java source code format.</p>
361 *
362 * <pre>
363 * CharUtils.unicodeEscaped(' ') = "\u0020"
364 * CharUtils.unicodeEscaped('A') = "\u0041"
365 * </pre>
366 *
367 * @param ch the character to convert
368 * @return the escaped Unicode string
369 */
370 public static String unicodeEscaped(char ch) {
371 if (ch < 0x10) {
372 return "\\u000" + Integer.toHexString(ch);
373 } else if (ch < 0x100) {
374 return "\\u00" + Integer.toHexString(ch);
375 } else if (ch < 0x1000) {
376 return "\\u0" + Integer.toHexString(ch);
377 }
378 return "\\u" + Integer.toHexString(ch);
379 }
380
381 /**
382 * <p>Converts the string to the Unicode format '\u0020'.</p>
383 *
384 * <p>This format is the Java source code format.</p>
385 *
386 * <p>If {@code null} is passed in, {@code null} will be returned.</p>
387 *
388 * <pre>
389 * CharUtils.unicodeEscaped(null) = null
390 * CharUtils.unicodeEscaped(' ') = "\u0020"
391 * CharUtils.unicodeEscaped('A') = "\u0041"
392 * </pre>
393 *
394 * @param ch the character to convert, may be null
395 * @return the escaped Unicode string, null if null input
396 */
397 public static String unicodeEscaped(Character ch) {
398 if (ch == null) {
399 return null;
400 }
401 return unicodeEscaped(ch.charValue());
402 }
403
404 //--------------------------------------------------------------------------
405 /**
406 * <p>Checks whether the character is ASCII 7 bit.</p>
407 *
408 * <pre>
409 * CharUtils.isAscii('a') = true
410 * CharUtils.isAscii('A') = true
411 * CharUtils.isAscii('3') = true
412 * CharUtils.isAscii('-') = true
413 * CharUtils.isAscii('\n') = true
414 * CharUtils.isAscii('©') = false
415 * </pre>
416 *
417 * @param ch the character to check
418 * @return true if less than 128
419 */
420 public static boolean isAscii(char ch) {
421 return ch < 128;
422 }
423
424 /**
425 * <p>Checks whether the character is ASCII 7 bit printable.</p>
426 *
427 * <pre>
428 * CharUtils.isAsciiPrintable('a') = true
429 * CharUtils.isAsciiPrintable('A') = true
430 * CharUtils.isAsciiPrintable('3') = true
431 * CharUtils.isAsciiPrintable('-') = true
432 * CharUtils.isAsciiPrintable('\n') = false
433 * CharUtils.isAsciiPrintable('©') = false
434 * </pre>
435 *
436 * @param ch the character to check
437 * @return true if between 32 and 126 inclusive
438 */
439 public static boolean isAsciiPrintable(char ch) {
440 return ch >= 32 && ch < 127;
441 }
442
443 /**
444 * <p>Checks whether the character is ASCII 7 bit control.</p>
445 *
446 * <pre>
447 * CharUtils.isAsciiControl('a') = false
448 * CharUtils.isAsciiControl('A') = false
449 * CharUtils.isAsciiControl('3') = false
450 * CharUtils.isAsciiControl('-') = false
451 * CharUtils.isAsciiControl('\n') = true
452 * CharUtils.isAsciiControl('©') = false
453 * </pre>
454 *
455 * @param ch the character to check
456 * @return true if less than 32 or equals 127
457 */
458 public static boolean isAsciiControl(char ch) {
459 return ch < 32 || ch == 127;
460 }
461
462 /**
463 * <p>Checks whether the character is ASCII 7 bit alphabetic.</p>
464 *
465 * <pre>
466 * CharUtils.isAsciiAlpha('a') = true
467 * CharUtils.isAsciiAlpha('A') = true
468 * CharUtils.isAsciiAlpha('3') = false
469 * CharUtils.isAsciiAlpha('-') = false
470 * CharUtils.isAsciiAlpha('\n') = false
471 * CharUtils.isAsciiAlpha('©') = false
472 * </pre>
473 *
474 * @param ch the character to check
475 * @return true if between 65 and 90 or 97 and 122 inclusive
476 */
477 public static boolean isAsciiAlpha(char ch) {
478 return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
479 }
480
481 /**
482 * <p>Checks whether the character is ASCII 7 bit alphabetic upper case.</p>
483 *
484 * <pre>
485 * CharUtils.isAsciiAlphaUpper('a') = false
486 * CharUtils.isAsciiAlphaUpper('A') = true
487 * CharUtils.isAsciiAlphaUpper('3') = false
488 * CharUtils.isAsciiAlphaUpper('-') = false
489 * CharUtils.isAsciiAlphaUpper('\n') = false
490 * CharUtils.isAsciiAlphaUpper('©') = false
491 * </pre>
492 *
493 * @param ch the character to check
494 * @return true if between 65 and 90 inclusive
495 */
496 public static boolean isAsciiAlphaUpper(char ch) {
497 return ch >= 'A' && ch <= 'Z';
498 }
499
500 /**
501 * <p>Checks whether the character is ASCII 7 bit alphabetic lower case.</p>
502 *
503 * <pre>
504 * CharUtils.isAsciiAlphaLower('a') = true
505 * CharUtils.isAsciiAlphaLower('A') = false
506 * CharUtils.isAsciiAlphaLower('3') = false
507 * CharUtils.isAsciiAlphaLower('-') = false
508 * CharUtils.isAsciiAlphaLower('\n') = false
509 * CharUtils.isAsciiAlphaLower('©') = false
510 * </pre>
511 *
512 * @param ch the character to check
513 * @return true if between 97 and 122 inclusive
514 */
515 public static boolean isAsciiAlphaLower(char ch) {
516 return ch >= 'a' && ch <= 'z';
517 }
518
519 /**
520 * <p>Checks whether the character is ASCII 7 bit numeric.</p>
521 *
522 * <pre>
523 * CharUtils.isAsciiNumeric('a') = false
524 * CharUtils.isAsciiNumeric('A') = false
525 * CharUtils.isAsciiNumeric('3') = true
526 * CharUtils.isAsciiNumeric('-') = false
527 * CharUtils.isAsciiNumeric('\n') = false
528 * CharUtils.isAsciiNumeric('©') = false
529 * </pre>
530 *
531 * @param ch the character to check
532 * @return true if between 48 and 57 inclusive
533 */
534 public static boolean isAsciiNumeric(char ch) {
535 return ch >= '0' && ch <= '9';
536 }
537
538 /**
539 * <p>Checks whether the character is ASCII 7 bit numeric.</p>
540 *
541 * <pre>
542 * CharUtils.isAsciiAlphanumeric('a') = true
543 * CharUtils.isAsciiAlphanumeric('A') = true
544 * CharUtils.isAsciiAlphanumeric('3') = true
545 * CharUtils.isAsciiAlphanumeric('-') = false
546 * CharUtils.isAsciiAlphanumeric('\n') = false
547 * CharUtils.isAsciiAlphanumeric('©') = false
548 * </pre>
549 *
550 * @param ch the character to check
551 * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
552 */
553 public static boolean isAsciiAlphanumeric(char ch) {
554 return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9');
555 }
556
557 }