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